Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1001 Fix load_json on joined tables #1002

Merged
merged 7 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions piccolo/query/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,9 @@ async def _process_results(self, results) -> QueryResponseType:
for column in json_columns:
if column._alias is not None:
json_column_names.append(column._alias)
elif column.json_operator is not None:
json_column_names.append(column._meta.name)
elif len(column._meta.call_chain) > 0:
json_column_names.append(
column.get_select_string(
engine_type=column._meta.engine_type
)
column._meta.get_default_alias().replace("$", ".")
)
else:
json_column_names.append(column._meta.name)
Expand Down
3 changes: 3 additions & 0 deletions tests/apps/migrations/commands/test_forwards_backwards.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from tests.example_apps.music.tables import (
Band,
Concert,
Instrument,
Manager,
Poster,
RecordingStudio,
Expand All @@ -33,6 +34,7 @@
Poster,
Shirt,
RecordingStudio,
Instrument,
]


Expand Down Expand Up @@ -211,6 +213,7 @@ def test_forwards_fake(self):
"2021-07-25T22:38:48:009306",
"2021-09-06T13:58:23:024723",
"2021-11-13T14:01:46:114725",
"2024-05-28T23:15:41:018844",
],
)

Expand Down
1 change: 1 addition & 0 deletions tests/apps/shell/commands/test_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ def test_run(self, print_: MagicMock, start_ipython_shell: MagicMock):
call("Importing music tables:"),
call("- Band"),
call("- Concert"),
call("- Instrument"),
call("- Manager"),
call("- Poster"),
call("- RecordingStudio"),
Expand Down
6 changes: 6 additions & 0 deletions tests/conf/test_apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from tests.example_apps.music.tables import (
Band,
Concert,
Instrument,
Manager,
Poster,
RecordingStudio,
Expand Down Expand Up @@ -113,6 +114,7 @@ def test_table_finder(self):
[
"Band",
"Concert",
"Instrument",
"Manager",
"Poster",
"RecordingStudio",
Expand All @@ -139,6 +141,7 @@ def test_table_finder_coercion(self):
[
"Band",
"Concert",
"Instrument",
"Manager",
"Poster",
"RecordingStudio",
Expand Down Expand Up @@ -182,6 +185,7 @@ def test_exclude_tags(self):
[
"Band",
"Concert",
"Instrument",
"Manager",
"RecordingStudio",
"Shirt",
Expand Down Expand Up @@ -228,6 +232,7 @@ def test_get_table_classes(self):
[
Band,
Concert,
Instrument,
Manager,
MegaTable,
Poster,
Expand All @@ -247,6 +252,7 @@ def test_get_table_classes(self):
[
Band,
Concert,
Instrument,
Manager,
Poster,
RecordingStudio,
Expand Down
1 change: 1 addition & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ async def drop_tables():
"musician",
"my_table",
"recording_studio",
"instrument",
"shirt",
"instrument",
"mega_table",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from piccolo.apps.migrations.auto.migration_manager import MigrationManager
from piccolo.columns.base import OnDelete, OnUpdate
from piccolo.columns.column_types import ForeignKey, Serial, Varchar
from piccolo.columns.indexes import IndexMethod
from piccolo.table import Table


class RecordingStudio(Table, tablename="recording_studio", schema=None):
id = Serial(
null=False,
primary_key=True,
unique=False,
index=False,
index_method=IndexMethod.btree,
choices=None,
db_column_name="id",
secret=False,
)


ID = "2024-05-28T23:15:41:018844"
VERSION = "1.5.1"
DESCRIPTION = ""


async def forwards():
manager = MigrationManager(
migration_id=ID, app_name="music", description=DESCRIPTION
)

manager.add_table(
class_name="Instrument",
tablename="instrument",
schema=None,
columns=None,
)

manager.add_column(
table_class_name="Instrument",
tablename="instrument",
column_name="name",
db_column_name="name",
column_class_name="Varchar",
column_class=Varchar,
params={
"length": 255,
"default": "",
"null": False,
"primary_key": False,
"unique": False,
"index": False,
"index_method": IndexMethod.btree,
"choices": None,
"db_column_name": None,
"secret": False,
},
schema=None,
)

manager.add_column(
table_class_name="Instrument",
tablename="instrument",
column_name="recording_studio",
db_column_name="recording_studio",
column_class_name="ForeignKey",
column_class=ForeignKey,
params={
"references": RecordingStudio,
"on_delete": OnDelete.cascade,
"on_update": OnUpdate.cascade,
"target_column": None,
"null": True,
"primary_key": False,
"unique": False,
"index": False,
"index_method": IndexMethod.btree,
"choices": None,
"db_column_name": None,
"secret": False,
},
schema=None,
)

return manager
10 changes: 10 additions & 0 deletions tests/example_apps/music/tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,13 @@ class RecordingStudio(Table):
id: Serial
facilities = JSON()
facilities_b = JSONB()


class Instrument(Table):
"""
Used for testing foreign keys to a table with a JSON column.
"""

id: Serial
name = Varchar()
recording_studio = ForeignKey(RecordingStudio)
124 changes: 88 additions & 36 deletions tests/table/test_output.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import json
from unittest import TestCase

from tests.base import DBTestCase, engine_is
from tests.example_apps.music.tables import Band, RecordingStudio
from piccolo.table import create_db_tables_sync, drop_db_tables_sync
from tests.base import DBTestCase
from tests.example_apps.music.tables import Band, Instrument, RecordingStudio


class TestOutputList(DBTestCase):
Expand Down Expand Up @@ -32,51 +33,102 @@ def test_output_as_json(self):


class TestOutputLoadJSON(TestCase):
tables = [RecordingStudio, Instrument]
json = {"a": 123}

def setUp(self):
RecordingStudio.create_table().run_sync()
create_db_tables_sync(*self.tables)

recording_studio = RecordingStudio(
{
RecordingStudio.facilities: self.json,
RecordingStudio.facilities_b: self.json,
}
)
recording_studio.save().run_sync()

instrument = Instrument(
{
Instrument.recording_studio: recording_studio,
Instrument.name: "Piccolo",
}
)
instrument.save().run_sync()

def tearDown(self):
RecordingStudio.alter().drop_table().run_sync()
drop_db_tables_sync(*self.tables)

def test_select(self):
json = {"a": 123}

RecordingStudio(facilities=json, facilities_b=json).save().run_sync()

results = RecordingStudio.select().output(load_json=True).run_sync()

if engine_is("cockroach"):
self.assertEqual(
results,
[
{
"id": results[0]["id"],
"facilities": {"a": 123},
"facilities_b": {"a": 123},
}
],
results = (
RecordingStudio.select(
RecordingStudio.facilities, RecordingStudio.facilities_b
)
else:
self.assertEqual(
results,
[
{
"id": 1,
"facilities": {"a": 123},
"facilities_b": {"a": 123},
}
],
.output(load_json=True)
.run_sync()
)

self.assertEqual(
results,
[
{
"facilities": self.json,
"facilities_b": self.json,
}
],
)

def test_join(self):
"""
Make sure it works correctly when the JSON column is on a joined table.

https://github.com/piccolo-orm/piccolo/issues/1001

"""
results = (
Instrument.select(
Instrument.name,
Instrument.recording_studio._.facilities,
)
.output(load_json=True)
.run_sync()
)

def test_objects(self):
json = {"a": 123}
self.assertEqual(
results,
[
{
"name": "Piccolo",
"recording_studio.facilities": self.json,
}
],
)

RecordingStudio(facilities=json, facilities_b=json).save().run_sync()
def test_join_with_alias(self):
results = (
Instrument.select(
Instrument.name,
Instrument.recording_studio._.facilities.as_alias(
"facilities"
),
)
.output(load_json=True)
.run_sync()
)

results = RecordingStudio.objects().output(load_json=True).run_sync()
self.assertEqual(
results,
[
{
"name": "Piccolo",
"facilities": self.json,
}
],
)

self.assertEqual(results[0].facilities, json)
self.assertEqual(results[0].facilities_b, json)
def test_objects(self):
results = RecordingStudio.objects().output(load_json=True).run_sync()
self.assertEqual(results[0].facilities, self.json)
self.assertEqual(results[0].facilities_b, self.json)


class TestOutputNested(DBTestCase):
Expand Down
Loading