piccolo 1.15.0__py3-none-any.whl → 1.17.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.
Files changed (39) hide show
  1. piccolo/__init__.py +1 -1
  2. piccolo/apps/asgi/commands/new.py +2 -2
  3. piccolo/apps/asgi/commands/templates/app/main.py.jinja +4 -0
  4. piccolo/apps/migrations/auto/migration_manager.py +22 -1
  5. piccolo/testing/test_case.py +120 -0
  6. {piccolo-1.15.0.dist-info → piccolo-1.17.0.dist-info}/METADATA +1 -1
  7. {piccolo-1.15.0.dist-info → piccolo-1.17.0.dist-info}/RECORD +39 -37
  8. {piccolo-1.15.0.dist-info → piccolo-1.17.0.dist-info}/WHEEL +1 -1
  9. tests/apps/migrations/auto/test_migration_manager.py +36 -1
  10. tests/columns/test_array.py +2 -1
  11. tests/columns/test_bigint.py +2 -1
  12. tests/columns/test_boolean.py +1 -1
  13. tests/columns/test_bytea.py +1 -1
  14. tests/columns/test_choices.py +2 -1
  15. tests/columns/test_date.py +1 -1
  16. tests/columns/test_double_precision.py +1 -1
  17. tests/columns/test_interval.py +1 -1
  18. tests/columns/test_json.py +1 -1
  19. tests/columns/test_jsonb.py +2 -1
  20. tests/columns/test_numeric.py +1 -1
  21. tests/columns/test_primary_key.py +1 -1
  22. tests/columns/test_readable.py +1 -1
  23. tests/columns/test_real.py +1 -1
  24. tests/columns/test_reference.py +1 -1
  25. tests/columns/test_reserved_column_names.py +1 -1
  26. tests/columns/test_smallint.py +2 -2
  27. tests/columns/test_time.py +2 -1
  28. tests/columns/test_timestamp.py +1 -1
  29. tests/columns/test_timestamptz.py +1 -1
  30. tests/columns/test_uuid.py +1 -1
  31. tests/columns/test_varchar.py +2 -2
  32. tests/query/functions/base.py +1 -1
  33. tests/query/functions/test_datetime.py +2 -1
  34. tests/query/functions/test_math.py +1 -1
  35. tests/table/test_refresh.py +2 -1
  36. tests/testing/test_test_case.py +65 -0
  37. {piccolo-1.15.0.dist-info → piccolo-1.17.0.dist-info}/LICENSE +0 -0
  38. {piccolo-1.15.0.dist-info → piccolo-1.17.0.dist-info}/entry_points.txt +0 -0
  39. {piccolo-1.15.0.dist-info → piccolo-1.17.0.dist-info}/top_level.txt +0 -0
piccolo/__init__.py CHANGED
@@ -1 +1 @@
1
- __VERSION__ = "1.15.0"
1
+ __VERSION__ = "1.17.0"
@@ -9,10 +9,10 @@ import colorama
9
9
  from jinja2 import Environment, FileSystemLoader
10
10
 
11
11
  TEMPLATE_DIR = os.path.join(os.path.dirname(__file__), "templates/app/")
12
- SERVERS = ["uvicorn", "Hypercorn"]
12
+ SERVERS = ["uvicorn", "Hypercorn", "granian"]
13
13
  ROUTER_DEPENDENCIES = {
14
14
  "starlette": ["starlette"],
15
- "fastapi": ["fastapi>=0.100.0"],
15
+ "fastapi": ["fastapi>=0.112.1"],
16
16
  "blacksheep": ["blacksheep"],
17
17
  "litestar": ["litestar"],
18
18
  "esmerald": ["esmerald"],
@@ -18,4 +18,8 @@ if __name__ == "__main__":
18
18
  asyncio.run(serve(app, CustomConfig()))
19
19
 
20
20
  serve(app)
21
+ {% elif server == 'granian' %}
22
+ import granian
23
+
24
+ granian.Granian("app:app", interface="asgi").serve()
21
25
  {% endif %}
@@ -130,11 +130,27 @@ class AlterColumnCollection:
130
130
  AsyncFunction = t.Callable[[], t.Coroutine]
131
131
 
132
132
 
133
+ class SkippedTransaction:
134
+ async def __aenter__(self):
135
+ print("Automatic transaction disabled")
136
+
137
+ async def __aexit__(self, *args, **kwargs):
138
+ pass
139
+
140
+
133
141
  @dataclass
134
142
  class MigrationManager:
135
143
  """
136
144
  Each auto generated migration returns a MigrationManager. It contains
137
145
  all of the schema changes that migration wants to make.
146
+
147
+ :param wrap_in_transaction:
148
+ By default, the migration is wrapped in a transaction, so if anything
149
+ fails, the whole migration will get rolled back. You can disable this
150
+ behaviour if you want - for example, in a manual migration you might
151
+ want to create the transaction yourself (perhaps you're using
152
+ savepoints), or you may want multiple transactions.
153
+
138
154
  """
139
155
 
140
156
  migration_id: str = ""
@@ -166,6 +182,7 @@ class MigrationManager:
166
182
  default_factory=list
167
183
  )
168
184
  fake: bool = False
185
+ wrap_in_transaction: bool = True
169
186
 
170
187
  def add_table(
171
188
  self,
@@ -935,7 +952,11 @@ class MigrationManager:
935
952
  if not engine:
936
953
  raise Exception("Can't find engine")
937
954
 
938
- async with engine.transaction():
955
+ async with (
956
+ engine.transaction()
957
+ if self.wrap_in_transaction
958
+ else SkippedTransaction()
959
+ ):
939
960
  if not self.preview:
940
961
  if direction == "backwards":
941
962
  raw_list = self.raw_backwards
@@ -0,0 +1,120 @@
1
+ from __future__ import annotations
2
+
3
+ import typing as t
4
+ from unittest import IsolatedAsyncioTestCase, TestCase
5
+
6
+ from piccolo.engine import Engine, engine_finder
7
+ from piccolo.table import (
8
+ Table,
9
+ create_db_tables,
10
+ create_db_tables_sync,
11
+ drop_db_tables,
12
+ drop_db_tables_sync,
13
+ )
14
+
15
+
16
+ class TableTest(TestCase):
17
+ """
18
+ Identical to :class:`AsyncTableTest <piccolo.testing.test_case.AsyncTableTest>`,
19
+ except it only work for sync tests. Only use this if you can't make your
20
+ tests async (perhaps you're on Python 3.7 where ``IsolatedAsyncioTestCase``
21
+ isn't available).
22
+
23
+ For example::
24
+
25
+ class TestBand(TableTest):
26
+ tables = [Band]
27
+
28
+ def test_band(self):
29
+ ...
30
+
31
+ """ # noqa: E501
32
+
33
+ tables: t.List[t.Type[Table]]
34
+
35
+ def setUp(self) -> None:
36
+ create_db_tables_sync(*self.tables)
37
+
38
+ def tearDown(self) -> None:
39
+ drop_db_tables_sync(*self.tables)
40
+
41
+
42
+ class AsyncTableTest(IsolatedAsyncioTestCase):
43
+ """
44
+ Used for tests where we need to create Piccolo tables - they will
45
+ automatically be created and dropped.
46
+
47
+ For example::
48
+
49
+ class TestBand(AsyncTableTest):
50
+ tables = [Band]
51
+
52
+ async def test_band(self):
53
+ ...
54
+
55
+ """
56
+
57
+ tables: t.List[t.Type[Table]]
58
+
59
+ async def asyncSetUp(self) -> None:
60
+ await create_db_tables(*self.tables)
61
+
62
+ async def asyncTearDown(self) -> None:
63
+ await drop_db_tables(*self.tables)
64
+
65
+
66
+ class AsyncTransactionTest(IsolatedAsyncioTestCase):
67
+ """
68
+ Wraps each test in a transaction, which is automatically rolled back when
69
+ the test finishes.
70
+
71
+ .. warning::
72
+ Python 3.11 and above only.
73
+
74
+ If your test suite just contains ``AsyncTransactionTest`` tests, then you
75
+ can setup your database tables once before your test suite runs. Any
76
+ changes made to your tables by the tests will be rolled back automatically.
77
+
78
+ Here's an example::
79
+
80
+ from piccolo.testing.test_case import AsyncTransactionTest
81
+
82
+
83
+ class TestBandEndpoint(AsyncTransactionTest):
84
+
85
+ async def test_band_response(self):
86
+ \"\"\"
87
+ Make sure the endpoint returns a 200.
88
+ \"\"\"
89
+ band = Band({Band.name: "Pythonistas"})
90
+ await band.save()
91
+
92
+ # Using an API testing client, like httpx:
93
+ response = await client.get(f"/bands/{band.id}/")
94
+ self.assertEqual(response.status_code, 200)
95
+
96
+ We add a ``Band`` to the database, but any subsequent tests won't see it,
97
+ as the changes are rolled back automatically.
98
+
99
+ """
100
+
101
+ # We use `engine_finder` to find the current `Engine`, but you can
102
+ # explicity set it here if you prefer:
103
+ #
104
+ # class MyTest(AsyncTransactionTest):
105
+ # db = DB
106
+ #
107
+ # ...
108
+ #
109
+ db: t.Optional[Engine] = None
110
+
111
+ async def asyncSetUp(self) -> None:
112
+ db = self.db or engine_finder()
113
+ assert db is not None
114
+ self.transaction = db.transaction()
115
+ # This is only available in Python 3.11 and above:
116
+ await self.enterAsyncContext(cm=self.transaction) # type: ignore
117
+
118
+ async def asyncTearDown(self):
119
+ await super().asyncTearDown()
120
+ await self.transaction.rollback()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: piccolo
3
- Version: 1.15.0
3
+ Version: 1.17.0
4
4
  Summary: A fast, user friendly ORM and query builder which supports asyncio.
5
5
  Home-page: https://github.com/piccolo-orm/piccolo
6
6
  Author: Daniel Townsend
@@ -1,4 +1,4 @@
1
- piccolo/__init__.py,sha256=PzCSZ5iBV_NCcXFBA13Mmkxa8tLr-WxcGYxYBnMCjhA,23
1
+ piccolo/__init__.py,sha256=tmCAvVvU3FZgyBipKPlPcMlzp1gqQfwg1VnJQ-UVzgY,23
2
2
  piccolo/custom_types.py,sha256=7HMQAze-5mieNLfbQ5QgbRQgR2abR7ol0qehv2SqROY,604
3
3
  piccolo/main.py,sha256=1VsFV67FWTUikPTysp64Fmgd9QBVa_9wcwKfwj2UCEA,5117
4
4
  piccolo/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -17,7 +17,7 @@ piccolo/apps/app/commands/templates/tables.py.jinja,sha256=revzdrvDDwe78VedBKz0z
17
17
  piccolo/apps/asgi/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
18
  piccolo/apps/asgi/piccolo_app.py,sha256=7VUvqQJbB-ScO0A62S6MiJmQL9F5DS-SdlqlDLbAblE,217
19
19
  piccolo/apps/asgi/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- piccolo/apps/asgi/commands/new.py,sha256=ZyYgwpBXb0t-0KQraeja6Y9ANjGEdZCXpu9bmm7_cPc,4230
20
+ piccolo/apps/asgi/commands/new.py,sha256=nLPdiLPpCmuIauH2xEjiue-H1rMv0A3YE0O0LmGXAQM,4241
21
21
  piccolo/apps/asgi/commands/templates/app/README.md.jinja,sha256=As3gNEZt9qcRmTVkjCzNtXJ8r4-3g0fCSe7Q-P39ezI,214
22
22
  piccolo/apps/asgi/commands/templates/app/_blacksheep_app.py.jinja,sha256=bgAGe0a9nWk0LAqK3VNDhPcKGqg0z8V-eIX2YmMoZLk,3117
23
23
  piccolo/apps/asgi/commands/templates/app/_esmerald_app.py.jinja,sha256=S-oYY6OFhwJA8PEYnrklQUkqtot3aXTmd7QGrW8Ufn4,2670
@@ -27,7 +27,7 @@ piccolo/apps/asgi/commands/templates/app/_litestar_app.py.jinja,sha256=oMH5KXoEY
27
27
  piccolo/apps/asgi/commands/templates/app/_starlette_app.py.jinja,sha256=vHcAzsS9I3OevYoznwZp8zucI4OEyUjj-EOAtscmlSE,1443
28
28
  piccolo/apps/asgi/commands/templates/app/app.py.jinja,sha256=gROY-LbHl8NtHDM_ntkI7Rjcbtg2ypDZ1FunBvpdjE4,458
29
29
  piccolo/apps/asgi/commands/templates/app/conftest.py.jinja,sha256=ZG1pRVMv3LhIfOsO3_08c_fF3EV4_EApuDHiIFFPJdk,497
30
- piccolo/apps/asgi/commands/templates/app/main.py.jinja,sha256=azwXyWZGkrIbZv5bZF_4Tvbly7AXkw5yFWGCHYImGeo,421
30
+ piccolo/apps/asgi/commands/templates/app/main.py.jinja,sha256=QxMpsevsxGQdL_xwfvcNalGLXGswgqiVvApitkP1TuQ,533
31
31
  piccolo/apps/asgi/commands/templates/app/piccolo_conf.py.jinja,sha256=f9Nb08_yipi0_mDUYrUvVoGCz7MRRS5QjCdUGBHN760,379
32
32
  piccolo/apps/asgi/commands/templates/app/piccolo_conf_test.py.jinja,sha256=ZB32IZQFjA67U7N7hD_wwZdbTdxAofj3-66EnX8Gqd0,235
33
33
  piccolo/apps/asgi/commands/templates/app/requirements.txt.jinja,sha256=w4FXnehMNsauBjf1OcJ547SL8uymhTKcjvSH60Nns7I,149
@@ -60,7 +60,7 @@ piccolo/apps/migrations/piccolo_app.py,sha256=1EcS2ComBPCaMCC2C3WaPR_GqLwt3XiIJN
60
60
  piccolo/apps/migrations/tables.py,sha256=jqBnK-Rk545v1Eu6GaLHTVz7-uwBTUnz2m58OA-mxTc,799
61
61
  piccolo/apps/migrations/auto/__init__.py,sha256=eYb1rZQaalumv_bhbcEe6x3dUglmpFtw7Egg6k7597U,316
62
62
  piccolo/apps/migrations/auto/diffable_table.py,sha256=FJ_D7FvL_vaThgIY-zFyW_kFmReOI12saM3DFcaAvfw,7058
63
- piccolo/apps/migrations/auto/migration_manager.py,sha256=kzkIbC9Ow2VoxI5uMcCDG-qVZbTHBtluvdawp-tIi20,35150
63
+ piccolo/apps/migrations/auto/migration_manager.py,sha256=tyAE1Xk6Xb58igbuHw3FGHhKkVjv_Vr5qBH4AbvVb8k,35856
64
64
  piccolo/apps/migrations/auto/operations.py,sha256=169IrCLR3FtTRxHsEHNg6dTG45lcEM7Aoyy3SwgX_hU,1329
65
65
  piccolo/apps/migrations/auto/schema_differ.py,sha256=VA1rK-_wNSdyZZgfA3ZOlpVGJCcvLyouKtT9k2YKhiA,26266
66
66
  piccolo/apps/migrations/auto/schema_snapshot.py,sha256=ZqUg4NpChOeoACKF2gkhqsz1BW3wOWFnzJCccq-CNNQ,4719
@@ -175,6 +175,7 @@ piccolo/query/methods/update.py,sha256=LfWqIXEl1aecc0rkVssTFmwyD6wXGhlKcTrUVhtlE
175
175
  piccolo/testing/__init__.py,sha256=pRFSqRInfx95AakOq54atmvqoB-ue073q2aR8u8zR40,83
176
176
  piccolo/testing/model_builder.py,sha256=lVEiEe71xrH8SSjzFc2l0s-VaCXHeg9Bo5oAYOEbLrI,6545
177
177
  piccolo/testing/random_builder.py,sha256=0LkGpanQ7P1R82gLIMQyK9cm1LdZkPvxbShTEf3jeH4,2128
178
+ piccolo/testing/test_case.py,sha256=JHQCIAeuO6H2ZbcFHQUhlvUWVFjzKoakDlqVYJvYhtg,3281
178
179
  piccolo/utils/__init__.py,sha256=SDFFraauI9Op8dCRkreQv1dwUcab8Mi1eC-n0EwlTy8,36
179
180
  piccolo/utils/dictionary.py,sha256=8vRPxgaXadDVhqihP1UxL7nUBgM6Gpe_Eu3xJq7zzGM,1886
180
181
  piccolo/utils/encoding.py,sha256=CtSODJOkT3TVHfGlTDXozDsClBCJbGGqluc6_UlJ-7c,1761
@@ -211,7 +212,7 @@ tests/apps/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
211
212
  tests/apps/migrations/test_migration.py,sha256=JmPLtf2BCWX3Yofe0GQe40m8I_yWa_-3vk1lDfFDfIo,308
212
213
  tests/apps/migrations/auto/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
213
214
  tests/apps/migrations/auto/test_diffable_table.py,sha256=bok3G9pwEYnE3AL6UG4iEHrVBZJQ_ovYCdKC3we5JVQ,2932
214
- tests/apps/migrations/auto/test_migration_manager.py,sha256=NTNx4y5B0bMVLUR9BybX3zS4jxFI3_weLej8zOn3BkI,34798
215
+ tests/apps/migrations/auto/test_migration_manager.py,sha256=L2raSuhZybRyK-BEh-G-nDndAgl4sLynekHQFqyrteY,35719
215
216
  tests/apps/migrations/auto/test_schema_differ.py,sha256=UdsaZisA02j15wr1bXkXD6Cqu3p0A23NwFQLXsJdQL4,19391
216
217
  tests/apps/migrations/auto/test_schema_snapshot.py,sha256=ZyvGZqn3N3cwd-3S-FME5AJ8buDSHesw7yPIvY6mE5k,6196
217
218
  tests/apps/migrations/auto/test_serialisation.py,sha256=EFkhES1w9h51UCamWrhxs3mf4I718ggeP7Yl5J_UID4,13548
@@ -244,33 +245,33 @@ tests/apps/user/commands/test_change_permissions.py,sha256=uVKEiT1EKot3VA2TDETdQ
244
245
  tests/apps/user/commands/test_create.py,sha256=iJ3Tti62rHwvdcTwNXrc5JPam6vR1qxKRdMN456vm3o,2250
245
246
  tests/apps/user/commands/test_list.py,sha256=ipPfGdW6fH7q-Jc7JcYUvlioGmH9GQU0WImZGC2m-XQ,2840
246
247
  tests/columns/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
247
- tests/columns/test_array.py,sha256=QixxML6vRq-PUliqbZSKd_LE5T4fEj5nq5e1NpOhng0,11590
248
+ tests/columns/test_array.py,sha256=niIkAPRQp49bkpbctaMgpcDai4TMAbM9qkrTGhPFsQY,11627
248
249
  tests/columns/test_base.py,sha256=CTqCNcrqAJTjLXe3MCZgTczrmB3jcVRcOpU4FilpLoQ,3918
249
- tests/columns/test_bigint.py,sha256=KqIw6UP3vGs3cyL1I1An8RfXMmjZvfSIuKYhgkqX5zI,1021
250
- tests/columns/test_boolean.py,sha256=dFqyUnzXU8JSflI511Vt3Gxk62lpIVgH37vnDEz0E2M,1611
251
- tests/columns/test_bytea.py,sha256=-XCXTKboPSfowhU7nceRnkhVCJ60Kus52b3f67xAlAo,1367
252
- tests/columns/test_choices.py,sha256=xDWgcguCH4pu8w3JpIcSyurpghPsbc4OQmzjup2iTIw,4029
250
+ tests/columns/test_bigint.py,sha256=KzfiItv0cYQZR35V_TL485AitDnOZQfTzC3C2YCLSn4,1058
251
+ tests/columns/test_boolean.py,sha256=qm0tg-gKcoYHNV1WVFxgbG4CsngxAJlg-hsGeTNklN8,1626
252
+ tests/columns/test_bytea.py,sha256=doN8S1eFVU4ntSXIg4IgMSZcbvqW1WJ-AEm3OjKLGkI,1382
253
+ tests/columns/test_choices.py,sha256=q8TLe7nvGERXyGO_XEryEBR-DuWwFY1jPpscsrXjdXo,4066
253
254
  tests/columns/test_combination.py,sha256=BuBwR7k5X1EkOWraZpjqU6gvtb6ow_k-7N1KQBiW2RA,1681
254
- tests/columns/test_date.py,sha256=WnwtCS81mYsDpwDrMnZRDjHA7ag-bxMPundRxtTlv1A,1015
255
+ tests/columns/test_date.py,sha256=QLC6kJMQwM-1mbUP4ksJVM7P8WwjzGZyynH3rHHdSew,1030
255
256
  tests/columns/test_db_column_name.py,sha256=v0QFOQp_atqzMB1n40simVwHeBDi5nyN1N2bSPX5k6w,7670
256
257
  tests/columns/test_defaults.py,sha256=rwlU1fXt3cCl7C51eLlZXqgWkE-K5W0pHvTrwkAKyCo,2896
257
- tests/columns/test_double_precision.py,sha256=Nx1vgmQqwn1PgBC6KcPO9yHKe9v8lCQXrEA1GcUJIn4,529
258
+ tests/columns/test_double_precision.py,sha256=7rhcSfDkb2fBh_zEG4UGwD_GW1sy6U9-8NooHuCS09Q,544
258
259
  tests/columns/test_get_sql_value.py,sha256=mKgsInN374jzV99y9mg_ZiG-AvnJgz36SZi89xL7RZM,1768
259
- tests/columns/test_interval.py,sha256=R3fyC7IX35neiu64XR7KX58ylpPzeU2zSEbaKdbW4I4,2765
260
- tests/columns/test_json.py,sha256=nbNXo0CISU8w3CjIF7nxBmRfEdenGFmc0o9YfhMvpKg,3467
261
- tests/columns/test_jsonb.py,sha256=Np3FZf3AspTGRWCCMrTYEsw6uTJPI8u3SZkOvH5ERRg,6690
262
- tests/columns/test_numeric.py,sha256=WrilQrWc-_g8DGLUvmllSBL01xqYqDORt3ypplnRizA,736
263
- tests/columns/test_primary_key.py,sha256=hXnTF-kFgrFNjawvJstmR3YQCM59qJ4NWkMD9vRY8FI,4871
264
- tests/columns/test_readable.py,sha256=OFK2n_k-eqRLdjEg1X2aOFPNwhtGDPNBli4DAh3i6vw,743
265
- tests/columns/test_real.py,sha256=bSjACkbnJzrN9dEWVb0UdWqSDfxdGz5HMWc8PUsJUl4,496
266
- tests/columns/test_reference.py,sha256=d7vm7AHinISA-HjlA8zyPCRaAGPtnc5NOXUvK4SeQFg,2329
267
- tests/columns/test_reserved_column_names.py,sha256=BpqN49n_AaiPjaaJ43hLhFXQHb8NV6ig8nvgKvN0Smc,1404
268
- tests/columns/test_smallint.py,sha256=t-LNX7XXy-k5_lhGXwELyC0LB9Iq4WrBVQdvEYf5EaQ,984
269
- tests/columns/test_time.py,sha256=qyG4jjSO_B2DfkjQo3nIff2T201c75EI7M6CYspK5QM,1560
270
- tests/columns/test_timestamp.py,sha256=lkb1pQW41kQ_c7zLjPfls7EgnIMnvG9AK3ePb5izJU0,1671
271
- tests/columns/test_timestamptz.py,sha256=Py27sx45-xQElhuLVxNtZjBxz3t6VJUbyUGW3H4W7eU,2615
272
- tests/columns/test_uuid.py,sha256=ifCyIrO6usYO33WM0FgwuPPhYzs4zVKD3MViIT61J7c,357
273
- tests/columns/test_varchar.py,sha256=Oyt8t7msCfIiZdU9B23zjlV6atFv4sX3iMSDJc565Oc,681
260
+ tests/columns/test_interval.py,sha256=2M18pfoGxLLosEvwTmuC4zQkM6jWwU0Nv2fqViW3xOs,2780
261
+ tests/columns/test_json.py,sha256=_cziJvw2uT8e_4u9lKhmU56lgQeE7bEqCXYf6AzfChA,3482
262
+ tests/columns/test_jsonb.py,sha256=eJQoxpyuQ4yrX-GMJhRkZntyd4tX6M6RhAxYn2-ISII,6727
263
+ tests/columns/test_numeric.py,sha256=AkTvdvjSsfRsMM79tx4AskUpsTizGBLMY_tC2OII9U4,751
264
+ tests/columns/test_primary_key.py,sha256=foNG9eTQUJ5yiEVQ7faIEMycW_VuZ7vgzknYXaZ-QXM,4886
265
+ tests/columns/test_readable.py,sha256=xKVfJuxZcfyncNVKXNryl2WFREX655jwD9DxiLArQiU,758
266
+ tests/columns/test_real.py,sha256=O_lwiNU4RIHSMY33QuWT0WTvNzV-2ATYYtdbI46E42c,511
267
+ tests/columns/test_reference.py,sha256=-pDKZl0kjRHz17U-_bldHD4rpg7Ga27lIzXMKOazbWA,2344
268
+ tests/columns/test_reserved_column_names.py,sha256=S39hq9Ex8QXlbnfjlPLtzwaxICTkXe43Nr2um1S37jI,1419
269
+ tests/columns/test_smallint.py,sha256=5tm8BpyUmun7uIROaKBgSb27dGu-waqtQAAvpvS66ek,1024
270
+ tests/columns/test_time.py,sha256=eQ4S-FMhULvkp6OwQaMbheBgQUVFCJ9JGMsKFpsM_vg,1597
271
+ tests/columns/test_timestamp.py,sha256=vD7F0J_8rZkX_PngfjaMcs5Ugq3lM8GUJXzU7cQLNZM,1686
272
+ tests/columns/test_timestamptz.py,sha256=P7zblPC6Fjjdk6iOhVUGIKnFFzbbUPVNSY98qbuqE7U,2630
273
+ tests/columns/test_uuid.py,sha256=taFYNvRZjQztMPbTQHYtwQutvcLnKPt6_aUxsf2o04Q,372
274
+ tests/columns/test_varchar.py,sha256=fbwBdimHoGaylfrqkFIgQ5m2q80umSoUNHIwofM6j_c,721
274
275
  tests/columns/m2m/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
275
276
  tests/columns/m2m/base.py,sha256=uH92ECQuY5AjpQXPySwrlruZPZzB4LH2V2FUSXmHRLQ,14563
276
277
  tests/columns/m2m/test_m2m.py,sha256=0ObmIHUJF6CZoNBznc5xXVr5_BbGBqOmWwtpg8IcPt4,13055
@@ -303,10 +304,10 @@ tests/query/test_gather.py,sha256=okWANrBoh0Ut1RomWoffiWNpFqiITF6qti-Aa3uYtRk,73
303
304
  tests/query/test_querystring.py,sha256=QrqyjwUlFlf5LrsJ7DgjCruq811I0UvrDFPud6rfZNI,5019
304
305
  tests/query/test_slots.py,sha256=I9ZjAYqAJNSFAWg9UyAqy7bm-Z52KiyQ2C_yHk2qqqI,1010
305
306
  tests/query/functions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
306
- tests/query/functions/base.py,sha256=sCIolQlvOMlnrLJJBAfJV-Tg8dCzkGnCs83JqRQpKkk,500
307
- tests/query/functions/test_datetime.py,sha256=247Vpbyuq0s-SU-883t6W5ghF8xiz44LzdHd2nJ0mZ4,2963
307
+ tests/query/functions/base.py,sha256=XbLpoSp05PPbGl7aSPW29GGrDKL2B-KsCxji7GhhPNI,515
308
+ tests/query/functions/test_datetime.py,sha256=X_5LR9XouPiQL-GQWen-NtokunCBHDuZ5gk9elNJNd4,3000
308
309
  tests/query/functions/test_functions.py,sha256=510fqRrOrAZ9NyFoZtlF6lIdiiLriWhZ7vvveWZ8rsc,1984
309
- tests/query/functions/test_math.py,sha256=nrHrThxurZIvbqlN4mjfxtKqLdBxOrWoeIZ_QCRJuTs,1271
310
+ tests/query/functions/test_math.py,sha256=wHaGQdEKISI8WeG9zGVNv62IrWSp4mMH3dPxVxoHy3s,1286
310
311
  tests/query/functions/test_string.py,sha256=RMojkBUzw1Ikrb3nTa7VjJ4FsKfrjpuHUyxQDA-F5Cs,1800
311
312
  tests/query/functions/test_type_conversion.py,sha256=WeYR9UfJnbidle07-akQ1g9hFCd93qT8xUhDF3c58n4,3235
312
313
  tests/query/mixins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -336,7 +337,7 @@ tests/table/test_objects.py,sha256=bir86ks-Ngy8x9Eu9bekOrh6twBYdEkIgTdbBWY6x9s,8
336
337
  tests/table/test_output.py,sha256=ZnpPbgVp79JcB6E_ooWQxOpOlhkwNUlMxC-1LSIEc2Y,4304
337
338
  tests/table/test_raw.py,sha256=9PTvYngQi41nYd5lKzkJdTqsEcwrdOXcvZjq-W26CwQ,1683
338
339
  tests/table/test_ref.py,sha256=eYNRnYHzNMXuMbV3B1ca5EidpIg4500q6hr1ccuVaso,269
339
- tests/table/test_refresh.py,sha256=VqTNT0_UGifCYr0wWVEXqI53G51RlMu0-oaw8tUTTLs,9213
340
+ tests/table/test_refresh.py,sha256=-BaLS6fZiR2RtQaFa7D9WGBjrbrss1-tt5xz1NE_m8E,9250
340
341
  tests/table/test_repr.py,sha256=uahz3_GffGQrf2mDE-4-Pu4AmSLBAyso6-9rbohCl58,446
341
342
  tests/table/test_select.py,sha256=jgeiahIlNFVijxYb3a54g1sJWVfH3llaYrsTBmdicrs,40390
342
343
  tests/table/test_str.py,sha256=eztWNULcjARR1fr9X5n4tojhDNgDfatVyNHwuYrzHAo,1731
@@ -353,6 +354,7 @@ tests/table/instance/test_to_dict.py,sha256=gkiYkmcI5qcy5E-ERWWmO-Q8uyVSFfcpJ8d5
353
354
  tests/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
354
355
  tests/testing/test_model_builder.py,sha256=bgs-cOYXtnrfgWydU2sZvs2N_Lt2T7La7AAMfIsOev4,6206
355
356
  tests/testing/test_random_builder.py,sha256=Upz9P1bhICVo0udI6Li-5eEdrXKbv8rMMLe0uK6pqB0,1694
357
+ tests/testing/test_test_case.py,sha256=qyDWYT44EZNyuWhaZXgSOpX48RaRw5u4FgNi87FYt2k,1691
356
358
  tests/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
357
359
  tests/utils/test_dictionary.py,sha256=GdWujlYQy6t09p2aQHPibkkPNbBYwkFwomKrVnztJTo,1480
358
360
  tests/utils/test_encoding.py,sha256=x1CHLm0rRheZaXz7at3SgkgcrZOmtMB-NtvJC77wQKE,326
@@ -365,9 +367,9 @@ tests/utils/test_sql_values.py,sha256=vzxRmy16FfLZPH-sAQexBvsF9MXB8n4smr14qoEOS5
365
367
  tests/utils/test_sync.py,sha256=9ytVo56y2vPQePvTeIi9lHIouEhWJbodl1TmzkGFrSo,799
366
368
  tests/utils/test_table_reflection.py,sha256=SIzuat-IpcVj1GCFyOWKShI8YkhdOPPFH7qVrvfyPNE,3794
367
369
  tests/utils/test_warnings.py,sha256=NvSC_cvJ6uZcwAGf1m-hLzETXCqprXELL8zg3TNLVMw,269
368
- piccolo-1.15.0.dist-info/LICENSE,sha256=zFIpi-16uIJ420UMIG75NU0JbDBykvrdnXcj5U_EYBI,1059
369
- piccolo-1.15.0.dist-info/METADATA,sha256=GGstF5gDdGfqb2J2-55eYcA9pbhIVN6W23Jir9GF4A4,5178
370
- piccolo-1.15.0.dist-info/WHEEL,sha256=R0nc6qTxuoLk7ShA2_Y-UWkN8ZdfDBG2B6Eqpz2WXbs,91
371
- piccolo-1.15.0.dist-info/entry_points.txt,sha256=SJPHET4Fi1bN5F3WqcKkv9SClK3_F1I7m4eQjk6AFh0,46
372
- piccolo-1.15.0.dist-info/top_level.txt,sha256=-SR74VGbk43VoPy1HH-mHm97yoGukLK87HE5kdBW6qM,24
373
- piccolo-1.15.0.dist-info/RECORD,,
370
+ piccolo-1.17.0.dist-info/LICENSE,sha256=zFIpi-16uIJ420UMIG75NU0JbDBykvrdnXcj5U_EYBI,1059
371
+ piccolo-1.17.0.dist-info/METADATA,sha256=HjbVcxKJlQbf47mpfUFb_AnX1LnlFYOoYvTuTX-iqm4,5178
372
+ piccolo-1.17.0.dist-info/WHEEL,sha256=nCVcAvsfA9TDtwGwhYaRrlPhTLV9m-Ga6mdyDtuwK18,91
373
+ piccolo-1.17.0.dist-info/entry_points.txt,sha256=SJPHET4Fi1bN5F3WqcKkv9SClK3_F1I7m4eQjk6AFh0,46
374
+ piccolo-1.17.0.dist-info/top_level.txt,sha256=-SR74VGbk43VoPy1HH-mHm97yoGukLK87HE5kdBW6qM,24
375
+ piccolo-1.17.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (72.1.0)
2
+ Generator: setuptools (73.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -2,7 +2,7 @@ import asyncio
2
2
  import random
3
3
  import typing as t
4
4
  from io import StringIO
5
- from unittest import TestCase
5
+ from unittest import IsolatedAsyncioTestCase, TestCase
6
6
  from unittest.mock import MagicMock, patch
7
7
 
8
8
  from piccolo.apps.migrations.auto.migration_manager import MigrationManager
@@ -11,6 +11,7 @@ from piccolo.columns import Text, Varchar
11
11
  from piccolo.columns.base import OnDelete, OnUpdate
12
12
  from piccolo.columns.column_types import ForeignKey
13
13
  from piccolo.conf.apps import AppConfig
14
+ from piccolo.engine import engine_finder
14
15
  from piccolo.table import Table, sort_table_classes
15
16
  from piccolo.utils.lazy_loader import LazyLoader
16
17
  from tests.base import AsyncMock, DBTestCase, engine_is, engines_only
@@ -1052,3 +1053,37 @@ class TestMigrationManager(DBTestCase):
1052
1053
  output,
1053
1054
  ' - 1 [preview forwards]... CREATE SCHEMA IF NOT EXISTS "schema_1"\nALTER TABLE "manager" SET SCHEMA "schema_1"\n', # noqa: E501
1054
1055
  )
1056
+
1057
+
1058
+ class TestWrapInTransaction(IsolatedAsyncioTestCase):
1059
+
1060
+ async def test_enabled(self):
1061
+ """
1062
+ Make sure we can wrap the migration in a transaction if we want to.
1063
+ """
1064
+
1065
+ async def run():
1066
+ db = engine_finder()
1067
+ assert db
1068
+ assert db.transaction_exists() is True
1069
+
1070
+ manager = MigrationManager(wrap_in_transaction=True)
1071
+ manager.add_raw(run)
1072
+
1073
+ await manager.run()
1074
+
1075
+ async def test_disabled(self):
1076
+ """
1077
+ Make sure we can stop the migration being wrapped in a transaction if
1078
+ we want to.
1079
+ """
1080
+
1081
+ async def run():
1082
+ db = engine_finder()
1083
+ assert db
1084
+ assert db.transaction_exists() is False
1085
+
1086
+ manager = MigrationManager(wrap_in_transaction=False)
1087
+ manager.add_raw(run)
1088
+
1089
+ await manager.run()
@@ -14,7 +14,8 @@ from piccolo.columns.column_types import (
14
14
  )
15
15
  from piccolo.querystring import QueryString
16
16
  from piccolo.table import Table
17
- from tests.base import TableTest, engines_only, engines_skip, sqlite_only
17
+ from piccolo.testing.test_case import TableTest
18
+ from tests.base import engines_only, engines_skip, sqlite_only
18
19
 
19
20
 
20
21
  class MyTable(Table):
@@ -2,7 +2,8 @@ import os
2
2
 
3
3
  from piccolo.columns.column_types import BigInt
4
4
  from piccolo.table import Table
5
- from tests.base import TableTest, engines_only
5
+ from piccolo.testing.test_case import TableTest
6
+ from tests.base import engines_only
6
7
 
7
8
 
8
9
  class MyTable(Table):
@@ -2,7 +2,7 @@ import typing as t
2
2
 
3
3
  from piccolo.columns.column_types import Boolean
4
4
  from piccolo.table import Table
5
- from tests.base import TableTest
5
+ from piccolo.testing.test_case import TableTest
6
6
 
7
7
 
8
8
  class MyTable(Table):
@@ -1,6 +1,6 @@
1
1
  from piccolo.columns.column_types import Bytea
2
2
  from piccolo.table import Table
3
- from tests.base import TableTest
3
+ from piccolo.testing.test_case import TableTest
4
4
 
5
5
 
6
6
  class MyTable(Table):
@@ -2,7 +2,8 @@ import enum
2
2
 
3
3
  from piccolo.columns.column_types import Array, Varchar
4
4
  from piccolo.table import Table
5
- from tests.base import TableTest, engines_only
5
+ from piccolo.testing.test_case import TableTest
6
+ from tests.base import engines_only
6
7
  from tests.example_apps.music.tables import Shirt
7
8
 
8
9
 
@@ -3,7 +3,7 @@ import datetime
3
3
  from piccolo.columns.column_types import Date
4
4
  from piccolo.columns.defaults.date import DateNow
5
5
  from piccolo.table import Table
6
- from tests.base import TableTest
6
+ from piccolo.testing.test_case import TableTest
7
7
 
8
8
 
9
9
  class MyTable(Table):
@@ -1,6 +1,6 @@
1
1
  from piccolo.columns.column_types import DoublePrecision
2
2
  from piccolo.table import Table
3
- from tests.base import TableTest
3
+ from piccolo.testing.test_case import TableTest
4
4
 
5
5
 
6
6
  class MyTable(Table):
@@ -3,7 +3,7 @@ import datetime
3
3
  from piccolo.columns.column_types import Interval
4
4
  from piccolo.columns.defaults.interval import IntervalCustom
5
5
  from piccolo.table import Table
6
- from tests.base import TableTest
6
+ from piccolo.testing.test_case import TableTest
7
7
 
8
8
 
9
9
  class MyTable(Table):
@@ -1,6 +1,6 @@
1
1
  from piccolo.columns.column_types import JSON
2
2
  from piccolo.table import Table
3
- from tests.base import TableTest
3
+ from piccolo.testing.test_case import TableTest
4
4
 
5
5
 
6
6
  class MyTable(Table):
@@ -1,6 +1,7 @@
1
1
  from piccolo.columns.column_types import JSONB, ForeignKey, Varchar
2
2
  from piccolo.table import Table
3
- from tests.base import TableTest, engines_only, engines_skip
3
+ from piccolo.testing.test_case import TableTest
4
+ from tests.base import engines_only, engines_skip
4
5
 
5
6
 
6
7
  class RecordingStudio(Table):
@@ -2,7 +2,7 @@ from decimal import Decimal
2
2
 
3
3
  from piccolo.columns.column_types import Numeric
4
4
  from piccolo.table import Table
5
- from tests.base import TableTest
5
+ from piccolo.testing.test_case import TableTest
6
6
 
7
7
 
8
8
  class MyTable(Table):
@@ -8,7 +8,7 @@ from piccolo.columns.column_types import (
8
8
  Varchar,
9
9
  )
10
10
  from piccolo.table import Table
11
- from tests.base import TableTest
11
+ from piccolo.testing.test_case import TableTest
12
12
 
13
13
 
14
14
  class MyTableDefaultPrimaryKey(Table):
@@ -1,7 +1,7 @@
1
1
  from piccolo import columns
2
2
  from piccolo.columns.readable import Readable
3
3
  from piccolo.table import Table
4
- from tests.base import TableTest
4
+ from piccolo.testing.test_case import TableTest
5
5
 
6
6
 
7
7
  class MyTable(Table):
@@ -1,6 +1,6 @@
1
1
  from piccolo.columns.column_types import Real
2
2
  from piccolo.table import Table
3
- from tests.base import TableTest
3
+ from piccolo.testing.test_case import TableTest
4
4
 
5
5
 
6
6
  class MyTable(Table):
@@ -8,7 +8,7 @@ from unittest import TestCase
8
8
  from piccolo.columns import ForeignKey, Varchar
9
9
  from piccolo.columns.reference import LazyTableReference
10
10
  from piccolo.table import Table
11
- from tests.base import TableTest
11
+ from piccolo.testing.test_case import TableTest
12
12
 
13
13
 
14
14
  class Band(Table):
@@ -1,6 +1,6 @@
1
1
  from piccolo.columns.column_types import Integer, Varchar
2
2
  from piccolo.table import Table
3
- from tests.base import TableTest
3
+ from piccolo.testing.test_case import TableTest
4
4
 
5
5
 
6
6
  class Concert(Table):
@@ -2,8 +2,8 @@ import os
2
2
 
3
3
  from piccolo.columns.column_types import SmallInt
4
4
  from piccolo.table import Table
5
-
6
- from ..base import TableTest, engines_only
5
+ from piccolo.testing.test_case import TableTest
6
+ from tests.base import engines_only
7
7
 
8
8
 
9
9
  class MyTable(Table):
@@ -4,7 +4,8 @@ from functools import partial
4
4
  from piccolo.columns.column_types import Time
5
5
  from piccolo.columns.defaults.time import TimeNow
6
6
  from piccolo.table import Table
7
- from tests.base import TableTest, engines_skip
7
+ from piccolo.testing.test_case import TableTest
8
+ from tests.base import engines_skip
8
9
 
9
10
 
10
11
  class MyTable(Table):
@@ -3,7 +3,7 @@ import datetime
3
3
  from piccolo.columns.column_types import Timestamp
4
4
  from piccolo.columns.defaults.timestamp import TimestampNow
5
5
  from piccolo.table import Table
6
- from tests.base import TableTest
6
+ from piccolo.testing.test_case import TableTest
7
7
 
8
8
 
9
9
  class MyTable(Table):
@@ -9,7 +9,7 @@ from piccolo.columns.defaults.timestamptz import (
9
9
  TimestamptzOffset,
10
10
  )
11
11
  from piccolo.table import Table
12
- from tests.base import TableTest
12
+ from piccolo.testing.test_case import TableTest
13
13
 
14
14
 
15
15
  class MyTable(Table):
@@ -2,7 +2,7 @@ import uuid
2
2
 
3
3
  from piccolo.columns.column_types import UUID
4
4
  from piccolo.table import Table
5
- from tests.base import TableTest
5
+ from piccolo.testing.test_case import TableTest
6
6
 
7
7
 
8
8
  class MyTable(Table):
@@ -1,7 +1,7 @@
1
1
  from piccolo.columns.column_types import Varchar
2
2
  from piccolo.table import Table
3
-
4
- from ..base import TableTest, engines_only
3
+ from piccolo.testing.test_case import TableTest
4
+ from tests.base import engines_only
5
5
 
6
6
 
7
7
  class MyTable(Table):
@@ -1,4 +1,4 @@
1
- from tests.base import TableTest
1
+ from piccolo.testing.test_case import TableTest
2
2
  from tests.example_apps.music.tables import Band, Manager
3
3
 
4
4
 
@@ -12,7 +12,8 @@ from piccolo.query.functions.datetime import (
12
12
  Year,
13
13
  )
14
14
  from piccolo.table import Table
15
- from tests.base import TableTest, engines_only, sqlite_only
15
+ from piccolo.testing.test_case import TableTest
16
+ from tests.base import engines_only, sqlite_only
16
17
 
17
18
 
18
19
  class Concert(Table):
@@ -3,7 +3,7 @@ import decimal
3
3
  from piccolo.columns import Numeric
4
4
  from piccolo.query.functions.math import Abs, Ceil, Floor, Round
5
5
  from piccolo.table import Table
6
- from tests.base import TableTest
6
+ from piccolo.testing.test_case import TableTest
7
7
 
8
8
 
9
9
  class Ticket(Table):
@@ -1,6 +1,7 @@
1
1
  import typing as t
2
2
 
3
- from tests.base import DBTestCase, TableTest
3
+ from piccolo.testing.test_case import TableTest
4
+ from tests.base import DBTestCase
4
5
  from tests.example_apps.music.tables import (
5
6
  Band,
6
7
  Concert,
@@ -0,0 +1,65 @@
1
+ import sys
2
+
3
+ import pytest
4
+
5
+ from piccolo.engine import engine_finder
6
+ from piccolo.testing.test_case import (
7
+ AsyncTableTest,
8
+ AsyncTransactionTest,
9
+ TableTest,
10
+ )
11
+ from tests.example_apps.music.tables import Band, Manager
12
+
13
+
14
+ class TestTableTest(TableTest):
15
+ """
16
+ Make sure the tables are created automatically.
17
+ """
18
+
19
+ tables = [Band, Manager]
20
+
21
+ async def test_tables_created(self):
22
+ self.assertTrue(Band.table_exists().run_sync())
23
+ self.assertTrue(Manager.table_exists().run_sync())
24
+
25
+
26
+ class TestAsyncTableTest(AsyncTableTest):
27
+ """
28
+ Make sure the tables are created automatically in async tests.
29
+ """
30
+
31
+ tables = [Band, Manager]
32
+
33
+ async def test_tables_created(self):
34
+ self.assertTrue(await Band.table_exists())
35
+ self.assertTrue(await Manager.table_exists())
36
+
37
+
38
+ @pytest.mark.skipif(sys.version_info <= (3, 11), reason="Python 3.11 required")
39
+ class TestAsyncTransaction(AsyncTransactionTest):
40
+ """
41
+ Make sure that the test exists within a transaction.
42
+ """
43
+
44
+ async def test_transaction_exists(self):
45
+ db = engine_finder()
46
+ assert db is not None
47
+ self.assertTrue(db.transaction_exists())
48
+
49
+
50
+ @pytest.mark.skipif(sys.version_info <= (3, 11), reason="Python 3.11 required")
51
+ class TestAsyncTransactionRolledBack(AsyncTransactionTest):
52
+ """
53
+ Make sure that the changes get rolled back automatically.
54
+ """
55
+
56
+ async def asyncTearDown(self):
57
+ await super().asyncTearDown()
58
+
59
+ assert Manager.table_exists().run_sync() is False
60
+
61
+ async def test_insert_data(self):
62
+ await Manager.create_table()
63
+
64
+ manager = Manager({Manager.name: "Guido"})
65
+ await manager.save()