piccolo 0.113.0__py3-none-any.whl → 0.115.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- piccolo/__init__.py +1 -1
- piccolo/apps/fixtures/commands/load.py +47 -6
- piccolo/apps/migrations/auto/migration_manager.py +1 -1
- piccolo/columns/m2m.py +11 -7
- piccolo/query/methods/count.py +26 -11
- piccolo/query/methods/select.py +67 -28
- piccolo/table.py +43 -5
- {piccolo-0.113.0.dist-info → piccolo-0.115.0.dist-info}/METADATA +1 -1
- {piccolo-0.113.0.dist-info → piccolo-0.115.0.dist-info}/RECORD +21 -18
- tests/apps/fixtures/commands/test_dump_load.py +39 -1
- tests/apps/migrations/auto/integration/test_migrations.py +34 -2
- tests/columns/m2m/__init__.py +0 -0
- tests/columns/{test_m2m.py → m2m/base.py} +55 -426
- tests/columns/m2m/test_m2m.py +436 -0
- tests/columns/m2m/test_m2m_schema.py +48 -0
- tests/table/test_count.py +73 -7
- tests/table/test_objects.py +4 -1
- {piccolo-0.113.0.dist-info → piccolo-0.115.0.dist-info}/LICENSE +0 -0
- {piccolo-0.113.0.dist-info → piccolo-0.115.0.dist-info}/WHEEL +0 -0
- {piccolo-0.113.0.dist-info → piccolo-0.115.0.dist-info}/entry_points.txt +0 -0
- {piccolo-0.113.0.dist-info → piccolo-0.115.0.dist-info}/top_level.txt +0 -0
@@ -1,69 +1,29 @@
|
|
1
|
-
import
|
2
|
-
import datetime
|
3
|
-
import decimal
|
4
|
-
import uuid
|
5
|
-
from unittest import TestCase
|
1
|
+
import typing as t
|
6
2
|
|
7
|
-
from tests.base import engine_is, engines_skip
|
8
|
-
|
9
|
-
try:
|
10
|
-
from asyncpg.pgproto.pgproto import UUID as asyncpgUUID
|
11
|
-
except ImportError:
|
12
|
-
# In case someone is running the tests for SQLite and doesn't have asyncpg
|
13
|
-
# installed.
|
14
|
-
from uuid import UUID as asyncpgUUID
|
15
|
-
|
16
|
-
from piccolo.columns.column_types import (
|
17
|
-
JSON,
|
18
|
-
JSONB,
|
19
|
-
UUID,
|
20
|
-
Array,
|
21
|
-
BigInt,
|
22
|
-
Boolean,
|
23
|
-
Bytea,
|
24
|
-
Date,
|
25
|
-
DoublePrecision,
|
26
|
-
ForeignKey,
|
27
|
-
Integer,
|
28
|
-
Interval,
|
29
|
-
LazyTableReference,
|
30
|
-
Numeric,
|
31
|
-
Real,
|
32
|
-
SmallInt,
|
33
|
-
Text,
|
34
|
-
Timestamp,
|
35
|
-
Timestamptz,
|
36
|
-
Varchar,
|
37
|
-
)
|
38
|
-
from piccolo.columns.m2m import M2M
|
39
3
|
from piccolo.engine.finder import engine_finder
|
40
4
|
from piccolo.table import Table, create_db_tables_sync, drop_db_tables_sync
|
5
|
+
from tests.base import engine_is, engines_skip
|
41
6
|
|
42
7
|
engine = engine_finder()
|
43
8
|
|
44
9
|
|
45
|
-
class
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
class Genre(Table):
|
51
|
-
name = Varchar()
|
52
|
-
bands = M2M(LazyTableReference("GenreToBand", module_path=__name__))
|
53
|
-
|
54
|
-
|
55
|
-
class GenreToBand(Table):
|
56
|
-
band = ForeignKey(Band)
|
57
|
-
genre = ForeignKey(Genre)
|
58
|
-
reason = Text(help_text="For testing additional columns on join tables.")
|
59
|
-
|
60
|
-
|
61
|
-
SIMPLE_SCHEMA = [Band, Genre, GenreToBand]
|
10
|
+
class M2MBase:
|
11
|
+
"""
|
12
|
+
This allows us to test M2M when the tables are in different schemas
|
13
|
+
(public vs non-public).
|
14
|
+
"""
|
62
15
|
|
16
|
+
band: t.Type[Table]
|
17
|
+
genre: t.Type[Table]
|
18
|
+
genre_to_band: t.Type[Table]
|
19
|
+
all_tables: t.List[t.Type[Table]]
|
63
20
|
|
64
|
-
class TestM2M(TestCase):
|
65
21
|
def setUp(self):
|
66
|
-
|
22
|
+
Band = self.band
|
23
|
+
Genre = self.genre
|
24
|
+
GenreToBand = self.genre_to_band
|
25
|
+
|
26
|
+
create_db_tables_sync(*self.all_tables, if_not_exists=True)
|
67
27
|
|
68
28
|
if engine_is("cockroach"):
|
69
29
|
bands = (
|
@@ -115,13 +75,16 @@ class TestM2M(TestCase):
|
|
115
75
|
).run_sync()
|
116
76
|
|
117
77
|
def tearDown(self):
|
118
|
-
drop_db_tables_sync(*
|
78
|
+
drop_db_tables_sync(*self.all_tables)
|
119
79
|
|
120
80
|
@engines_skip("cockroach")
|
121
81
|
def test_select_name(self):
|
122
82
|
"""
|
123
83
|
🐛 Cockroach bug: https://github.com/cockroachdb/cockroach/issues/71908 "could not decorrelate subquery" error under asyncpg
|
124
84
|
""" # noqa: E501
|
85
|
+
Band = self.band
|
86
|
+
Genre = self.genre
|
87
|
+
|
125
88
|
response = Band.select(
|
126
89
|
Band.name, Band.genres(Genre.name, as_list=True)
|
127
90
|
).run_sync()
|
@@ -155,6 +118,10 @@ class TestM2M(TestCase):
|
|
155
118
|
"""
|
156
119
|
🐛 Cockroach bug: https://github.com/cockroachdb/cockroach/issues/71908 "could not decorrelate subquery" error under asyncpg
|
157
120
|
""" # noqa: E501
|
121
|
+
Band = self.band
|
122
|
+
Genre = self.genre
|
123
|
+
GenreToBand = self.genre_to_band
|
124
|
+
|
158
125
|
GenreToBand.delete(force=True).run_sync()
|
159
126
|
|
160
127
|
# Try it with a list response
|
@@ -189,6 +156,9 @@ class TestM2M(TestCase):
|
|
189
156
|
"""
|
190
157
|
🐛 Cockroach bug: https://github.com/cockroachdb/cockroach/issues/71908 "could not decorrelate subquery" error under asyncpg
|
191
158
|
""" # noqa: E501
|
159
|
+
Band = self.band
|
160
|
+
Genre = self.genre
|
161
|
+
|
192
162
|
response = Band.select(
|
193
163
|
Band.name, Band.genres(Genre.id, Genre.name)
|
194
164
|
).run_sync()
|
@@ -248,6 +218,9 @@ class TestM2M(TestCase):
|
|
248
218
|
"""
|
249
219
|
🐛 Cockroach bug: https://github.com/cockroachdb/cockroach/issues/71908 "could not decorrelate subquery" error under asyncpg
|
250
220
|
""" # noqa: E501
|
221
|
+
Band = self.band
|
222
|
+
Genre = self.genre
|
223
|
+
|
251
224
|
response = Band.select(
|
252
225
|
Band.name, Band.genres(Genre.id, as_list=True)
|
253
226
|
).run_sync()
|
@@ -284,6 +257,9 @@ class TestM2M(TestCase):
|
|
284
257
|
🐛 Cockroach bug: https://github.com/cockroachdb/cockroach/issues/71908 "could not decorrelate subquery" error under asyncpg
|
285
258
|
|
286
259
|
""" # noqa: E501
|
260
|
+
Band = self.band
|
261
|
+
Genre = self.genre
|
262
|
+
|
287
263
|
response = Band.select(
|
288
264
|
Band.name, Band.genres(Genre.all_columns(exclude=(Genre.id,)))
|
289
265
|
).run_sync()
|
@@ -312,6 +288,10 @@ class TestM2M(TestCase):
|
|
312
288
|
"""
|
313
289
|
Make sure we can add items to the joining table.
|
314
290
|
"""
|
291
|
+
Band = self.band
|
292
|
+
Genre = self.genre
|
293
|
+
GenreToBand = self.genre_to_band
|
294
|
+
|
315
295
|
band: Band = Band.objects().get(Band.name == "Pythonistas").run_sync()
|
316
296
|
band.add_m2m(Genre(name="Punk Rock"), m2m=Band.genres).run_sync()
|
317
297
|
|
@@ -334,6 +314,10 @@ class TestM2M(TestCase):
|
|
334
314
|
Make sure the ``extra_column_values`` parameter for ``add_m2m`` works
|
335
315
|
correctly when the dictionary keys are strings.
|
336
316
|
"""
|
317
|
+
Band = self.band
|
318
|
+
Genre = self.genre
|
319
|
+
GenreToBand = self.genre_to_band
|
320
|
+
|
337
321
|
reason = "Their second album was very punk rock."
|
338
322
|
|
339
323
|
band: Band = Band.objects().get(Band.name == "Pythonistas").run_sync()
|
@@ -361,6 +345,10 @@ class TestM2M(TestCase):
|
|
361
345
|
Make sure the ``extra_column_values`` parameter for ``add_m2m`` works
|
362
346
|
correctly when the dictionary keys are ``Column`` classes.
|
363
347
|
"""
|
348
|
+
Band = self.band
|
349
|
+
Genre = self.genre
|
350
|
+
GenreToBand = self.genre_to_band
|
351
|
+
|
364
352
|
reason = "Their second album was very punk rock."
|
365
353
|
|
366
354
|
band: Band = Band.objects().get(Band.name == "Pythonistas").run_sync()
|
@@ -387,6 +375,10 @@ class TestM2M(TestCase):
|
|
387
375
|
"""
|
388
376
|
Make sure we can add an existing element to the joining table.
|
389
377
|
"""
|
378
|
+
Band = self.band
|
379
|
+
Genre = self.genre
|
380
|
+
GenreToBand = self.genre_to_band
|
381
|
+
|
390
382
|
band: Band = Band.objects().get(Band.name == "Pythonistas").run_sync()
|
391
383
|
|
392
384
|
genre: Genre = (
|
@@ -414,6 +406,8 @@ class TestM2M(TestCase):
|
|
414
406
|
"""
|
415
407
|
Make sure we can get related items via the joining table.
|
416
408
|
"""
|
409
|
+
Band = self.band
|
410
|
+
|
417
411
|
band: Band = Band.objects().get(Band.name == "Pythonistas").run_sync()
|
418
412
|
|
419
413
|
genres = band.get_m2m(Band.genres).run_sync()
|
@@ -426,6 +420,10 @@ class TestM2M(TestCase):
|
|
426
420
|
"""
|
427
421
|
Make sure we can remove related items via the joining table.
|
428
422
|
"""
|
423
|
+
Band = self.band
|
424
|
+
Genre = self.genre
|
425
|
+
GenreToBand = self.genre_to_band
|
426
|
+
|
429
427
|
band: Band = Band.objects().get(Band.name == "Pythonistas").run_sync()
|
430
428
|
|
431
429
|
genre = Genre.objects().get(Genre.name == "Rock").run_sync()
|
@@ -462,372 +460,3 @@ class TestM2M(TestCase):
|
|
462
460
|
.run_sync(),
|
463
461
|
1,
|
464
462
|
)
|
465
|
-
|
466
|
-
|
467
|
-
###############################################################################
|
468
|
-
|
469
|
-
# A schema using custom primary keys
|
470
|
-
|
471
|
-
|
472
|
-
class Customer(Table):
|
473
|
-
uuid = UUID(primary_key=True)
|
474
|
-
name = Varchar()
|
475
|
-
concerts = M2M(
|
476
|
-
LazyTableReference("CustomerToConcert", module_path=__name__)
|
477
|
-
)
|
478
|
-
|
479
|
-
|
480
|
-
class Concert(Table):
|
481
|
-
uuid = UUID(primary_key=True)
|
482
|
-
name = Varchar()
|
483
|
-
customers = M2M(
|
484
|
-
LazyTableReference("CustomerToConcert", module_path=__name__)
|
485
|
-
)
|
486
|
-
|
487
|
-
|
488
|
-
class CustomerToConcert(Table):
|
489
|
-
customer = ForeignKey(Customer)
|
490
|
-
concert = ForeignKey(Concert)
|
491
|
-
|
492
|
-
|
493
|
-
CUSTOM_PK_SCHEMA = [Customer, Concert, CustomerToConcert]
|
494
|
-
|
495
|
-
|
496
|
-
class TestM2MCustomPrimaryKey(TestCase):
|
497
|
-
"""
|
498
|
-
Make sure the M2M functionality works correctly when the tables have custom
|
499
|
-
primary key columns.
|
500
|
-
"""
|
501
|
-
|
502
|
-
def setUp(self):
|
503
|
-
create_db_tables_sync(*CUSTOM_PK_SCHEMA, if_not_exists=True)
|
504
|
-
|
505
|
-
bob = Customer.objects().create(name="Bob").run_sync()
|
506
|
-
sally = Customer.objects().create(name="Sally").run_sync()
|
507
|
-
fred = Customer.objects().create(name="Fred").run_sync()
|
508
|
-
|
509
|
-
rockfest = Concert.objects().create(name="Rockfest").run_sync()
|
510
|
-
folkfest = Concert.objects().create(name="Folkfest").run_sync()
|
511
|
-
classicfest = Concert.objects().create(name="Classicfest").run_sync()
|
512
|
-
|
513
|
-
CustomerToConcert.insert(
|
514
|
-
CustomerToConcert(customer=bob, concert=rockfest),
|
515
|
-
CustomerToConcert(customer=bob, concert=classicfest),
|
516
|
-
CustomerToConcert(customer=sally, concert=rockfest),
|
517
|
-
CustomerToConcert(customer=sally, concert=folkfest),
|
518
|
-
CustomerToConcert(customer=fred, concert=classicfest),
|
519
|
-
).run_sync()
|
520
|
-
|
521
|
-
def tearDown(self):
|
522
|
-
drop_db_tables_sync(*CUSTOM_PK_SCHEMA)
|
523
|
-
|
524
|
-
@engines_skip("cockroach")
|
525
|
-
def test_select(self):
|
526
|
-
"""
|
527
|
-
🐛 Cockroach bug: https://github.com/cockroachdb/cockroach/issues/71908 "could not decorrelate subquery" error under asyncpg
|
528
|
-
""" # noqa: E501
|
529
|
-
response = Customer.select(
|
530
|
-
Customer.name, Customer.concerts(Concert.name, as_list=True)
|
531
|
-
).run_sync()
|
532
|
-
|
533
|
-
self.assertListEqual(
|
534
|
-
response,
|
535
|
-
[
|
536
|
-
{"name": "Bob", "concerts": ["Rockfest", "Classicfest"]},
|
537
|
-
{"name": "Sally", "concerts": ["Rockfest", "Folkfest"]},
|
538
|
-
{"name": "Fred", "concerts": ["Classicfest"]},
|
539
|
-
],
|
540
|
-
)
|
541
|
-
|
542
|
-
# Now try it in reverse.
|
543
|
-
response = Concert.select(
|
544
|
-
Concert.name, Concert.customers(Customer.name, as_list=True)
|
545
|
-
).run_sync()
|
546
|
-
|
547
|
-
self.assertListEqual(
|
548
|
-
response,
|
549
|
-
[
|
550
|
-
{"name": "Rockfest", "customers": ["Bob", "Sally"]},
|
551
|
-
{"name": "Folkfest", "customers": ["Sally"]},
|
552
|
-
{"name": "Classicfest", "customers": ["Bob", "Fred"]},
|
553
|
-
],
|
554
|
-
)
|
555
|
-
|
556
|
-
def test_add_m2m(self):
|
557
|
-
"""
|
558
|
-
Make sure we can add items to the joining table.
|
559
|
-
"""
|
560
|
-
customer: Customer = (
|
561
|
-
Customer.objects().get(Customer.name == "Bob").run_sync()
|
562
|
-
)
|
563
|
-
customer.add_m2m(
|
564
|
-
Concert(name="Jazzfest"), m2m=Customer.concerts
|
565
|
-
).run_sync()
|
566
|
-
|
567
|
-
self.assertTrue(
|
568
|
-
Concert.exists().where(Concert.name == "Jazzfest").run_sync()
|
569
|
-
)
|
570
|
-
|
571
|
-
self.assertEqual(
|
572
|
-
CustomerToConcert.count()
|
573
|
-
.where(
|
574
|
-
CustomerToConcert.customer.name == "Bob",
|
575
|
-
CustomerToConcert.concert.name == "Jazzfest",
|
576
|
-
)
|
577
|
-
.run_sync(),
|
578
|
-
1,
|
579
|
-
)
|
580
|
-
|
581
|
-
def test_add_m2m_within_transaction(self):
|
582
|
-
"""
|
583
|
-
Make sure we can add items to the joining table, when within an
|
584
|
-
existing transaction.
|
585
|
-
|
586
|
-
https://github.com/piccolo-orm/piccolo/issues/674
|
587
|
-
|
588
|
-
"""
|
589
|
-
engine = Customer._meta.db
|
590
|
-
|
591
|
-
async def add_m2m_in_transaction():
|
592
|
-
async with engine.transaction():
|
593
|
-
customer: Customer = await Customer.objects().get(
|
594
|
-
Customer.name == "Bob"
|
595
|
-
)
|
596
|
-
await customer.add_m2m(
|
597
|
-
Concert(name="Jazzfest"), m2m=Customer.concerts
|
598
|
-
)
|
599
|
-
|
600
|
-
asyncio.run(add_m2m_in_transaction())
|
601
|
-
|
602
|
-
self.assertTrue(
|
603
|
-
Concert.exists().where(Concert.name == "Jazzfest").run_sync()
|
604
|
-
)
|
605
|
-
|
606
|
-
self.assertEqual(
|
607
|
-
CustomerToConcert.count()
|
608
|
-
.where(
|
609
|
-
CustomerToConcert.customer.name == "Bob",
|
610
|
-
CustomerToConcert.concert.name == "Jazzfest",
|
611
|
-
)
|
612
|
-
.run_sync(),
|
613
|
-
1,
|
614
|
-
)
|
615
|
-
|
616
|
-
def test_get_m2m(self):
|
617
|
-
"""
|
618
|
-
Make sure we can get related items via the joining table.
|
619
|
-
"""
|
620
|
-
customer: Customer = (
|
621
|
-
Customer.objects().get(Customer.name == "Bob").run_sync()
|
622
|
-
)
|
623
|
-
|
624
|
-
concerts = customer.get_m2m(Customer.concerts).run_sync()
|
625
|
-
|
626
|
-
self.assertTrue(all(isinstance(i, Table) for i in concerts))
|
627
|
-
|
628
|
-
self.assertCountEqual(
|
629
|
-
[i.name for i in concerts], ["Rockfest", "Classicfest"]
|
630
|
-
)
|
631
|
-
|
632
|
-
|
633
|
-
###############################################################################
|
634
|
-
|
635
|
-
# Test a very complex schema
|
636
|
-
|
637
|
-
|
638
|
-
class SmallTable(Table):
|
639
|
-
varchar_col = Varchar()
|
640
|
-
mega_rows = M2M(LazyTableReference("SmallToMega", module_path=__name__))
|
641
|
-
|
642
|
-
|
643
|
-
if engine.engine_type != "cockroach": # type: ignore
|
644
|
-
|
645
|
-
class MegaTable(Table): # type: ignore
|
646
|
-
"""
|
647
|
-
A table containing all of the column types and different column kwargs
|
648
|
-
"""
|
649
|
-
|
650
|
-
array_col = Array(Varchar())
|
651
|
-
bigint_col = BigInt()
|
652
|
-
boolean_col = Boolean()
|
653
|
-
bytea_col = Bytea()
|
654
|
-
date_col = Date()
|
655
|
-
double_precision_col = DoublePrecision()
|
656
|
-
integer_col = Integer()
|
657
|
-
interval_col = Interval()
|
658
|
-
json_col = JSON()
|
659
|
-
jsonb_col = JSONB()
|
660
|
-
numeric_col = Numeric(digits=(5, 2))
|
661
|
-
real_col = Real()
|
662
|
-
smallint_col = SmallInt()
|
663
|
-
text_col = Text()
|
664
|
-
timestamp_col = Timestamp()
|
665
|
-
timestamptz_col = Timestamptz()
|
666
|
-
uuid_col = UUID()
|
667
|
-
varchar_col = Varchar()
|
668
|
-
|
669
|
-
else:
|
670
|
-
|
671
|
-
class MegaTable(Table): # type: ignore
|
672
|
-
"""
|
673
|
-
Special version for Cockroach.
|
674
|
-
A table containing all of the column types and different column kwargs
|
675
|
-
"""
|
676
|
-
|
677
|
-
array_col = Array(Varchar())
|
678
|
-
bigint_col = BigInt()
|
679
|
-
boolean_col = Boolean()
|
680
|
-
bytea_col = Bytea()
|
681
|
-
date_col = Date()
|
682
|
-
double_precision_col = DoublePrecision()
|
683
|
-
integer_col = BigInt()
|
684
|
-
interval_col = Interval()
|
685
|
-
json_col = JSONB()
|
686
|
-
jsonb_col = JSONB()
|
687
|
-
numeric_col = Numeric(digits=(5, 2))
|
688
|
-
real_col = Real()
|
689
|
-
smallint_col = SmallInt()
|
690
|
-
text_col = Text()
|
691
|
-
timestamp_col = Timestamp()
|
692
|
-
timestamptz_col = Timestamptz()
|
693
|
-
uuid_col = UUID()
|
694
|
-
varchar_col = Varchar()
|
695
|
-
|
696
|
-
|
697
|
-
class SmallToMega(Table):
|
698
|
-
small = ForeignKey(MegaTable)
|
699
|
-
mega = ForeignKey(SmallTable)
|
700
|
-
|
701
|
-
|
702
|
-
COMPLEX_SCHEMA = [MegaTable, SmallTable, SmallToMega]
|
703
|
-
|
704
|
-
|
705
|
-
class TestM2MComplexSchema(TestCase):
|
706
|
-
"""
|
707
|
-
By using a very complex schema containing every column type, we can catch
|
708
|
-
more edge cases.
|
709
|
-
"""
|
710
|
-
|
711
|
-
def setUp(self):
|
712
|
-
create_db_tables_sync(*COMPLEX_SCHEMA, if_not_exists=True)
|
713
|
-
|
714
|
-
small_table = SmallTable(varchar_col="Test")
|
715
|
-
small_table.save().run_sync()
|
716
|
-
|
717
|
-
mega_table = MegaTable(
|
718
|
-
array_col=["bob", "sally"],
|
719
|
-
bigint_col=1,
|
720
|
-
boolean_col=True,
|
721
|
-
bytea_col="hello".encode("utf8"),
|
722
|
-
date_col=datetime.date(year=2021, month=1, day=1),
|
723
|
-
double_precision_col=1.344,
|
724
|
-
integer_col=1,
|
725
|
-
interval_col=datetime.timedelta(seconds=10),
|
726
|
-
json_col={"a": 1},
|
727
|
-
jsonb_col={"a": 1},
|
728
|
-
numeric_col=decimal.Decimal("1.1"),
|
729
|
-
real_col=1.1,
|
730
|
-
smallint_col=1,
|
731
|
-
text_col="hello",
|
732
|
-
timestamp_col=datetime.datetime(year=2021, month=1, day=1),
|
733
|
-
timestamptz_col=datetime.datetime(
|
734
|
-
year=2021, month=1, day=1, tzinfo=datetime.timezone.utc
|
735
|
-
),
|
736
|
-
uuid_col=uuid.UUID("12783854-c012-4c15-8183-8eecb46f2c4e"),
|
737
|
-
varchar_col="hello",
|
738
|
-
)
|
739
|
-
mega_table.save().run_sync()
|
740
|
-
|
741
|
-
SmallToMega(small=small_table, mega=mega_table).save().run_sync()
|
742
|
-
|
743
|
-
self.mega_table = mega_table
|
744
|
-
|
745
|
-
def tearDown(self):
|
746
|
-
drop_db_tables_sync(*COMPLEX_SCHEMA)
|
747
|
-
|
748
|
-
@engines_skip("cockroach")
|
749
|
-
def test_select_all(self):
|
750
|
-
"""
|
751
|
-
Fetch all of the columns from the related table to make sure they're
|
752
|
-
returned correctly.
|
753
|
-
"""
|
754
|
-
"""
|
755
|
-
🐛 Cockroach bug: https://github.com/cockroachdb/cockroach/issues/71908 "could not decorrelate subquery" error under asyncpg
|
756
|
-
""" # noqa: E501
|
757
|
-
response = SmallTable.select(
|
758
|
-
SmallTable.varchar_col, SmallTable.mega_rows(load_json=True)
|
759
|
-
).run_sync()
|
760
|
-
|
761
|
-
self.assertEqual(len(response), 1)
|
762
|
-
mega_rows = response[0]["mega_rows"]
|
763
|
-
|
764
|
-
self.assertEqual(len(mega_rows), 1)
|
765
|
-
mega_row = mega_rows[0]
|
766
|
-
|
767
|
-
for key, value in mega_row.items():
|
768
|
-
# Make sure that every value in the response matches what we saved.
|
769
|
-
self.assertAlmostEqual(
|
770
|
-
getattr(self.mega_table, key),
|
771
|
-
value,
|
772
|
-
msg=f"{key} doesn't match",
|
773
|
-
)
|
774
|
-
|
775
|
-
@engines_skip("cockroach")
|
776
|
-
def test_select_single(self):
|
777
|
-
"""
|
778
|
-
Make sure each column can be selected one at a time.
|
779
|
-
"""
|
780
|
-
"""
|
781
|
-
🐛 Cockroach bug: https://github.com/cockroachdb/cockroach/issues/71908 "could not decorrelate subquery" error under asyncpg
|
782
|
-
""" # noqa: E501
|
783
|
-
for column in MegaTable._meta.columns:
|
784
|
-
response = SmallTable.select(
|
785
|
-
SmallTable.varchar_col,
|
786
|
-
SmallTable.mega_rows(column, load_json=True),
|
787
|
-
).run_sync()
|
788
|
-
|
789
|
-
data = response[0]["mega_rows"][0]
|
790
|
-
column_name = column._meta.name
|
791
|
-
|
792
|
-
original_value = getattr(self.mega_table, column_name)
|
793
|
-
returned_value = data[column_name]
|
794
|
-
|
795
|
-
if type(column) == UUID:
|
796
|
-
self.assertIn(type(returned_value), (uuid.UUID, asyncpgUUID))
|
797
|
-
else:
|
798
|
-
self.assertEqual(
|
799
|
-
type(original_value),
|
800
|
-
type(returned_value),
|
801
|
-
msg=f"{column_name} type isn't correct",
|
802
|
-
)
|
803
|
-
|
804
|
-
self.assertAlmostEqual(
|
805
|
-
original_value,
|
806
|
-
returned_value,
|
807
|
-
msg=f"{column_name} doesn't match",
|
808
|
-
)
|
809
|
-
|
810
|
-
# Test it as a list too
|
811
|
-
response = SmallTable.select(
|
812
|
-
SmallTable.varchar_col,
|
813
|
-
SmallTable.mega_rows(column, as_list=True, load_json=True),
|
814
|
-
).run_sync()
|
815
|
-
|
816
|
-
original_value = getattr(self.mega_table, column_name)
|
817
|
-
returned_value = response[0]["mega_rows"][0]
|
818
|
-
|
819
|
-
if type(column) == UUID:
|
820
|
-
self.assertIn(type(returned_value), (uuid.UUID, asyncpgUUID))
|
821
|
-
self.assertEqual(str(original_value), str(returned_value))
|
822
|
-
else:
|
823
|
-
self.assertEqual(
|
824
|
-
type(original_value),
|
825
|
-
type(returned_value),
|
826
|
-
msg=f"{column_name} type isn't correct",
|
827
|
-
)
|
828
|
-
|
829
|
-
self.assertAlmostEqual(
|
830
|
-
original_value,
|
831
|
-
returned_value,
|
832
|
-
msg=f"{column_name} doesn't match",
|
833
|
-
)
|