piccolo 1.5.0__py3-none-any.whl → 1.5.2__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 CHANGED
@@ -1 +1 @@
1
- __VERSION__ = "1.5.0"
1
+ __VERSION__ = "1.5.2"
@@ -16,6 +16,7 @@ ROUTER_DEPENDENCIES = {
16
16
  "blacksheep": ["blacksheep"],
17
17
  "litestar": ["litestar"],
18
18
  "esmerald": ["esmerald"],
19
+ "lilya": ["lilya"],
19
20
  }
20
21
  ROUTERS = list(ROUTER_DEPENDENCIES.keys())
21
22
 
@@ -0,0 +1,45 @@
1
+ from piccolo_admin.endpoints import create_admin
2
+ from piccolo_api.crud.endpoints import PiccoloCRUD
3
+ from piccolo.engine import engine_finder
4
+ from lilya.routing import Path, Include
5
+ from lilya.apps import Lilya
6
+ from lilya.staticfiles import StaticFiles
7
+
8
+ from home.endpoints import HomeController
9
+ from home.piccolo_app import APP_CONFIG
10
+ from home.tables import Task
11
+
12
+
13
+ app = Lilya(
14
+ routes=[
15
+ Path("/", HomeController),
16
+ Include(
17
+ "/admin/",
18
+ create_admin(
19
+ tables=APP_CONFIG.table_classes,
20
+ # Required when running under HTTPS:
21
+ # allowed_hosts=['my_site.com']
22
+ )
23
+ ),
24
+ Include("/static/", StaticFiles(directory="static")),
25
+ Include("/tasks/", PiccoloCRUD(table=Task))
26
+ ],
27
+ )
28
+
29
+
30
+ @app.on_event("on_startup")
31
+ async def open_database_connection_pool():
32
+ try:
33
+ engine = engine_finder()
34
+ await engine.start_connection_pool()
35
+ except Exception:
36
+ print("Unable to connect to the database")
37
+
38
+
39
+ @app.on_event("on_shutdown")
40
+ async def close_database_connection_pool():
41
+ try:
42
+ engine = engine_finder()
43
+ await engine.close_connection_pool()
44
+ except Exception:
45
+ print("Unable to connect to the database")
@@ -8,4 +8,6 @@
8
8
  {% include '_litestar_app.py.jinja' %}
9
9
  {% elif router == 'esmerald' %}
10
10
  {% include '_esmerald_app.py.jinja' %}
11
+ {% elif router == 'lilya' %}
12
+ {% include '_lilya_app.py.jinja' %}
11
13
  {% endif %}
@@ -0,0 +1,21 @@
1
+ import os
2
+
3
+ import jinja2
4
+ from lilya.controllers import Controller
5
+ from lilya.responses import HTMLResponse
6
+
7
+
8
+ ENVIRONMENT = jinja2.Environment(
9
+ loader=jinja2.FileSystemLoader(
10
+ searchpath=os.path.join(os.path.dirname(__file__), "templates")
11
+ )
12
+ )
13
+
14
+
15
+ class HomeController(Controller):
16
+ async def get(self, request):
17
+ template = ENVIRONMENT.get_template("home.html.jinja")
18
+
19
+ content = template.render(title="Piccolo + ASGI",)
20
+
21
+ return HTMLResponse(content)
@@ -6,4 +6,6 @@
6
6
  {% include '_litestar_endpoints.py.jinja' %}
7
7
  {% elif router == 'esmerald' %}
8
8
  {% include '_esmerald_endpoints.py.jinja' %}
9
+ {% elif router == 'lilya' %}
10
+ {% include '_lilya_endpoints.py.jinja' %}
9
11
  {% endif %}
@@ -61,6 +61,11 @@
61
61
  <li><a href="/admin/">Admin</a></li>
62
62
  <li><a href="/docs/swagger">Swagger API</a></li>
63
63
  </ul>
64
+ <h3>Lilya</h3>
65
+ <ul>
66
+ <li><a href="/admin/">Admin</a></li>
67
+ <li><a href="/tasks/">JSON endpoint</a></li>
68
+ </ul>
64
69
  </section>
65
70
  </div>
66
71
  {% endblock content %}
@@ -78,9 +78,11 @@ class BackwardsMigrationManager(BaseMigrationManager):
78
78
  _continue = (
79
79
  "y"
80
80
  if self.auto_agree
81
- else input(f"Reverse {n} migration{'s' if n != 1 else ''}? [y/N] ")
81
+ else input(
82
+ f"Reverse {n} migration{'s' if n != 1 else ''}? [y/N] "
83
+ ).lower()
82
84
  )
83
- if _continue in "yY":
85
+ if _continue == "y":
84
86
  for migration_id in reversed_migration_ids:
85
87
  migration_module = migration_modules[migration_id]
86
88
  response = await migration_module.forwards()
@@ -131,10 +133,10 @@ async def run_backwards(
131
133
  "apps:\n"
132
134
  f"{', '.join(names)}\n"
133
135
  "Are you sure you want to continue? [y/N] "
134
- )
136
+ ).lower()
135
137
  )
136
138
 
137
- if _continue not in "yY":
139
+ if _continue != "y":
138
140
  return MigrationResult(success=False, message="user cancelled")
139
141
  for _app_name in sorted_app_names:
140
142
  print_heading(_app_name)
@@ -5,7 +5,6 @@ for interacting with the data using Piccolo.
5
5
 
6
6
  import datetime
7
7
  import sys
8
- import typing as t
9
8
  import uuid
10
9
  from decimal import Decimal
11
10
  from enum import Enum
@@ -14,10 +13,12 @@ from piccolo.columns import (
14
13
  JSON,
15
14
  UUID,
16
15
  Boolean,
16
+ Date,
17
17
  ForeignKey,
18
18
  Integer,
19
19
  Interval,
20
20
  Numeric,
21
+ Serial,
21
22
  Timestamp,
22
23
  Varchar,
23
24
  )
@@ -29,6 +30,7 @@ from piccolo.utils.warnings import colored_string
29
30
 
30
31
 
31
32
  class Manager(Table):
33
+ id: Serial
32
34
  name = Varchar(length=50)
33
35
 
34
36
  @classmethod
@@ -40,6 +42,7 @@ class Manager(Table):
40
42
 
41
43
 
42
44
  class Band(Table):
45
+ id: Serial
43
46
  name = Varchar(length=50)
44
47
  manager = ForeignKey(references=Manager, null=True)
45
48
  popularity = Integer()
@@ -53,6 +56,7 @@ class Band(Table):
53
56
 
54
57
 
55
58
  class Venue(Table):
59
+ id: Serial
56
60
  name = Varchar(length=100)
57
61
  capacity = Integer(default=0)
58
62
 
@@ -65,6 +69,7 @@ class Venue(Table):
65
69
 
66
70
 
67
71
  class Concert(Table):
72
+ id: Serial
68
73
  band_1 = ForeignKey(Band)
69
74
  band_2 = ForeignKey(Band)
70
75
  venue = ForeignKey(Venue)
@@ -89,6 +94,7 @@ class Ticket(Table):
89
94
  standing = "standing"
90
95
  premium = "premium"
91
96
 
97
+ id: Serial
92
98
  concert = ForeignKey(Concert)
93
99
  price = Numeric(digits=(5, 2))
94
100
  ticket_type = Varchar(choices=TicketType, default=TicketType.standing)
@@ -98,13 +104,14 @@ class Ticket(Table):
98
104
  return Readable(
99
105
  template="%s - %s",
100
106
  columns=[
101
- t.cast(t.Type[Venue], cls.concert.venue).name,
107
+ cls.concert._.venue._.name,
102
108
  cls.ticket_type,
103
109
  ],
104
110
  )
105
111
 
106
112
 
107
113
  class DiscountCode(Table):
114
+ id: Serial
108
115
  code = UUID()
109
116
  active = Boolean(default=True, null=True)
110
117
 
@@ -117,6 +124,7 @@ class DiscountCode(Table):
117
124
 
118
125
 
119
126
  class RecordingStudio(Table):
127
+ id: Serial
120
128
  name = Varchar(length=100)
121
129
  facilities = JSON(null=True)
122
130
 
@@ -128,7 +136,31 @@ class RecordingStudio(Table):
128
136
  )
129
137
 
130
138
 
131
- TABLES = (Manager, Band, Venue, Concert, Ticket, DiscountCode, RecordingStudio)
139
+ class Album(Table):
140
+ id: Serial
141
+ name = Varchar()
142
+ band = ForeignKey(Band)
143
+ release_date = Date()
144
+ recorded_at = ForeignKey(RecordingStudio)
145
+
146
+ @classmethod
147
+ def get_readable(cls) -> Readable:
148
+ return Readable(
149
+ template="%s - %s",
150
+ columns=[cls.name, cls.band._.name],
151
+ )
152
+
153
+
154
+ TABLES = (
155
+ Manager,
156
+ Band,
157
+ Venue,
158
+ Concert,
159
+ Ticket,
160
+ DiscountCode,
161
+ RecordingStudio,
162
+ Album,
163
+ )
132
164
 
133
165
 
134
166
  def populate():
@@ -184,24 +216,44 @@ def populate():
184
216
  *[DiscountCode({DiscountCode.code: uuid.uuid4()}) for _ in range(5)]
185
217
  ).run_sync()
186
218
 
187
- RecordingStudio.insert(
188
- RecordingStudio(
219
+ recording_studio_1 = RecordingStudio(
220
+ {
221
+ RecordingStudio.name: "Abbey Road",
222
+ RecordingStudio.facilities: {
223
+ "restaurant": True,
224
+ "mixing_desk": True,
225
+ },
226
+ }
227
+ )
228
+ recording_studio_1.save().run_sync()
229
+
230
+ recording_studio_2 = RecordingStudio(
231
+ {
232
+ RecordingStudio.name: "Electric Lady",
233
+ RecordingStudio.facilities: {
234
+ "restaurant": False,
235
+ "mixing_desk": True,
236
+ },
237
+ },
238
+ )
239
+ recording_studio_2.save().run_sync()
240
+
241
+ Album.insert(
242
+ Album(
189
243
  {
190
- RecordingStudio.name: "Abbey Road",
191
- RecordingStudio.facilities: {
192
- "restaurant": True,
193
- "mixing_desk": True,
194
- },
244
+ Album.name: "Awesome album 1",
245
+ Album.recorded_at: recording_studio_1,
246
+ Album.band: pythonistas,
247
+ Album.release_date: datetime.date(year=2021, month=1, day=1),
195
248
  }
196
249
  ),
197
- RecordingStudio(
250
+ Album(
198
251
  {
199
- RecordingStudio.name: "Electric Lady",
200
- RecordingStudio.facilities: {
201
- "restaurant": False,
202
- "mixing_desk": True,
203
- },
204
- },
252
+ Album.name: "Awesome album 2",
253
+ Album.recorded_at: recording_studio_2,
254
+ Album.band: rustaceans,
255
+ Album.release_date: datetime.date(year=2022, month=2, day=2),
256
+ }
205
257
  ),
206
258
  ).run_sync()
207
259
 
@@ -278,7 +330,7 @@ def run(
278
330
 
279
331
  populate()
280
332
 
281
- from IPython.core.interactiveshell import _asyncio_runner
333
+ from IPython.core.async_helpers import _asyncio_runner
282
334
 
283
335
  if ipython_profile:
284
336
  print(colored_string("Using your IPython profile\n"))
piccolo/query/base.py CHANGED
@@ -87,13 +87,9 @@ class Query(t.Generic[TableInstance, QueryResponseType]):
87
87
  for column in json_columns:
88
88
  if column._alias is not None:
89
89
  json_column_names.append(column._alias)
90
- elif column.json_operator is not None:
91
- json_column_names.append(column._meta.name)
92
90
  elif len(column._meta.call_chain) > 0:
93
91
  json_column_names.append(
94
- column.get_select_string(
95
- engine_type=column._meta.engine_type
96
- )
92
+ column._meta.get_default_alias().replace("$", ".")
97
93
  )
98
94
  else:
99
95
  json_column_names.append(column._meta.name)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: piccolo
3
- Version: 1.5.0
3
+ Version: 1.5.2
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
@@ -144,7 +144,7 @@ Let Piccolo scaffold you an ASGI web app, using Piccolo as the ORM:
144
144
  piccolo asgi new
145
145
  ```
146
146
 
147
- [Starlette](https://www.starlette.io/), [FastAPI](https://fastapi.tiangolo.com/), [BlackSheep](https://www.neoteroi.dev/blacksheep/), [Litestar](https://litestar.dev/) and [Esmerald](https://esmerald.dev/) are currently supported.
147
+ [Starlette](https://www.starlette.io/), [FastAPI](https://fastapi.tiangolo.com/), [BlackSheep](https://www.neoteroi.dev/blacksheep/), [Litestar](https://litestar.dev/), [Esmerald](https://esmerald.dev/) and [Lilya](https://lilya.dev) are currently supported.
148
148
 
149
149
  ## Are you a Django user?
150
150
 
@@ -1,4 +1,4 @@
1
- piccolo/__init__.py,sha256=qES-IZ6zqJOP7rIsdL8ARFeVec9WeO-kd278gxhW7Ks,22
1
+ piccolo/__init__.py,sha256=f_QOyG9IZDoR-FbyiLGFmbPuPBY4CR9EZgrInXOyPUo,22
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,14 +17,15 @@ 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=vZHSI2Pyh9cnVKbjPIiXEVFJ4JWfO-iBOCwvJSfPJyw,4206
20
+ piccolo/apps/asgi/commands/new.py,sha256=ZyYgwpBXb0t-0KQraeja6Y9ANjGEdZCXpu9bmm7_cPc,4230
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
24
24
  piccolo/apps/asgi/commands/templates/app/_fastapi_app.py.jinja,sha256=cCmRVAN8gw6zfHBcLI_NxapwN7LGM5QSXM7K94imDh8,2436
25
+ piccolo/apps/asgi/commands/templates/app/_lilya_app.py.jinja,sha256=8rV1p-POGHkFIqvHvlE5wWwWPZweuSnMJhwreLMgLo8,1259
25
26
  piccolo/apps/asgi/commands/templates/app/_litestar_app.py.jinja,sha256=oMH5KXoEYhf9qgXNj2Kepc6prps1MQECufdUduaiwe4,2815
26
27
  piccolo/apps/asgi/commands/templates/app/_starlette_app.py.jinja,sha256=YvNUlJuTd4mj-pm3WQKbQq3w3x3VfDb_Wz6aQLUsORo,1271
27
- piccolo/apps/asgi/commands/templates/app/app.py.jinja,sha256=_ILj6Ap1AvAP55ZxrbNedTVsXr9klW3eh-GRf9WTQLs,389
28
+ piccolo/apps/asgi/commands/templates/app/app.py.jinja,sha256=gROY-LbHl8NtHDM_ntkI7Rjcbtg2ypDZ1FunBvpdjE4,458
28
29
  piccolo/apps/asgi/commands/templates/app/conftest.py.jinja,sha256=ZG1pRVMv3LhIfOsO3_08c_fF3EV4_EApuDHiIFFPJdk,497
29
30
  piccolo/apps/asgi/commands/templates/app/main.py.jinja,sha256=azwXyWZGkrIbZv5bZF_4Tvbly7AXkw5yFWGCHYImGeo,421
30
31
  piccolo/apps/asgi/commands/templates/app/piccolo_conf.py.jinja,sha256=f9Nb08_yipi0_mDUYrUvVoGCz7MRRS5QjCdUGBHN760,379
@@ -33,14 +34,15 @@ piccolo/apps/asgi/commands/templates/app/requirements.txt.jinja,sha256=w4FXnehMN
33
34
  piccolo/apps/asgi/commands/templates/app/home/__init__.py.jinja,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
35
  piccolo/apps/asgi/commands/templates/app/home/_blacksheep_endpoints.py.jinja,sha256=Rri_xzDkl87G5ME74qTxY25cwKIKufuzgkRsy__mNts,510
35
36
  piccolo/apps/asgi/commands/templates/app/home/_esmerald_endpoints.py.jinja,sha256=D_Slfc3IfTyBgq_VUIG5_AW5pVvvSqn-YGQspxMJNsE,499
37
+ piccolo/apps/asgi/commands/templates/app/home/_lilya_endpoints.py.jinja,sha256=nKSJ9VPTUTaLD9oDqAUseNuQkcPLBxShPAEfZK15rSE,490
36
38
  piccolo/apps/asgi/commands/templates/app/home/_litestar_endpoints.py.jinja,sha256=zXbYXDXFeeOCXmWBa_QK0kWGlBnv6T_A2jOHuvp9oCs,553
37
39
  piccolo/apps/asgi/commands/templates/app/home/_starlette_endpoints.py.jinja,sha256=KEjNEUKiZNBIWYAt9EgPHe4yCbkKLtlhaCBce9YI-RQ,498
38
- piccolo/apps/asgi/commands/templates/app/home/endpoints.py.jinja,sha256=G8Anx5v4Xszo0h0uCAduhWsXZDWluJvhMp0cr4kRezM,353
40
+ piccolo/apps/asgi/commands/templates/app/home/endpoints.py.jinja,sha256=Vc7pllhzKeNyj1XPzqdRH1AUpv7D4pooBIrUMt6gK7I,428
39
41
  piccolo/apps/asgi/commands/templates/app/home/piccolo_app.py.jinja,sha256=4gETiW9ukTNsomeJOvrRkqPbToZ_FU0b3LsNIaEYyP8,505
40
42
  piccolo/apps/asgi/commands/templates/app/home/tables.py.jinja,sha256=wk34RAsuoFn5iJ4OHlQzUqgatq6QB2G9tFE0BYkaers,197
41
43
  piccolo/apps/asgi/commands/templates/app/home/piccolo_migrations/README.md,sha256=ji6UOtHvzHX-eS_qhhKTN36ZXNZ7QwtjwjdE4Qgm35A,59
42
44
  piccolo/apps/asgi/commands/templates/app/home/templates/base.html.jinja_raw,sha256=3RqiNuyAap_P-xNK3uhNaQQ6rC365VzPmRqmmXSLO8o,451
43
- piccolo/apps/asgi/commands/templates/app/home/templates/home.html.jinja_raw,sha256=yfIE_m6qAEjY8v-W16p7gN1LPYrtyCVWictgyiuoqlM,2461
45
+ piccolo/apps/asgi/commands/templates/app/home/templates/home.html.jinja_raw,sha256=QJI0MY0hydMdqPg9YcW7XmmccJ1PyHvOSRIvMJX3ij0,2637
44
46
  piccolo/apps/asgi/commands/templates/app/static/favicon.ico,sha256=IvcgeJHObd9kj2mNIXkJdXYxMU8OaOymyYQWnWfbtHo,7406
45
47
  piccolo/apps/asgi/commands/templates/app/static/main.css,sha256=vudarPLglQ6NOgJiNeU2x0yQl0DiWScqb09QZv2wAzM,1056
46
48
  piccolo/apps/fixtures/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -65,7 +67,7 @@ piccolo/apps/migrations/auto/schema_snapshot.py,sha256=ZqUg4NpChOeoACKF2gkhqsz1B
65
67
  piccolo/apps/migrations/auto/serialisation.py,sha256=nlomUL-TwD_7Gjb8ttRZfIwn9VbNoEmRmD3LElP5e0k,23927
66
68
  piccolo/apps/migrations/auto/serialisation_legacy.py,sha256=Edqx3YL0RGTsTHLNkHRNnXdfX6ut1h65U7UX2cI_BkE,1752
67
69
  piccolo/apps/migrations/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
- piccolo/apps/migrations/commands/backwards.py,sha256=DYynglPXtzK4zUxmSOfOhjJArq95mv0mf8WWwzrKQOM,6575
70
+ piccolo/apps/migrations/commands/backwards.py,sha256=i96eR6_P7IJQDtbaPmIleDg0nCoZubP2P2hNOLtbbT8,6615
69
71
  piccolo/apps/migrations/commands/base.py,sha256=v-uEfoSNpiHJivBO1YUc3yyDqwXyADIl53xNo_LnRZM,4475
70
72
  piccolo/apps/migrations/commands/check.py,sha256=VdaIjs3FFy_nwN6kjGKMoVQ4zp1Bdoej756UJBj79Pk,3982
71
73
  piccolo/apps/migrations/commands/clean.py,sha256=XD4xqtqkL5ZqnwIghzo5Yo2UnBAeznBVyrTiw6SnaCQ,2855
@@ -75,7 +77,7 @@ piccolo/apps/migrations/commands/templates/migration.py.jinja,sha256=wMC8RTIcQj3
75
77
  piccolo/apps/playground/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
78
  piccolo/apps/playground/piccolo_app.py,sha256=zs6nGxt-lgUF8nEwI0uDTNZDKQqjZaNDH8le5RqrMNE,222
77
79
  piccolo/apps/playground/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
78
- piccolo/apps/playground/commands/run.py,sha256=ajXYy2UqU47QGQ3vmXbSvpwR8h7kbMV8W4QFCLJBHhE,7351
80
+ piccolo/apps/playground/commands/run.py,sha256=RhuxsnQj8m7iE2ww_de7Jz-dT25gbqMdx1MWeHQ2mCg,8401
79
81
  piccolo/apps/project/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
80
82
  piccolo/apps/project/piccolo_app.py,sha256=mT3O0m3QcCfS0oOr3jt0QZ9TX6gUavGPjJeNn2C_fdM,220
81
83
  piccolo/apps/project/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -144,7 +146,7 @@ piccolo/engine/finder.py,sha256=GjzBNtzRzH79fjtRn7OI3nZiOXE8JfoQWAvHVPrPNx4,507
144
146
  piccolo/engine/postgres.py,sha256=zUY6x52QrZ8waiqEUuqlVFiXyzAXrsFi3PY5EJnv3DM,18276
145
147
  piccolo/engine/sqlite.py,sha256=h5RrrDqy-28ck8L9SkLURfZWFSTcVdojTLDt1w8cTgk,22099
146
148
  piccolo/query/__init__.py,sha256=1R0cRo8xoycUTFbSZzmW5rndH-wW4DDqsWJQgTELiWU,683
147
- piccolo/query/base.py,sha256=dcYkEy_fhOUoiRn7u7lVsoWUKe90Z7jDu5zir1teRB8,15397
149
+ piccolo/query/base.py,sha256=G8Mwz0GcHY4Xs5Co9ubCNMI-3orfOsDdRDOnFRws7TU,15212
148
150
  piccolo/query/mixins.py,sha256=3oFksbYSaNGz_F7XJRhTTMHK4Pdf8-FUfDMpdy7rsNM,21639
149
151
  piccolo/query/proxy.py,sha256=Yq4jNc7IWJvdeO3u7_7iPyRy2WhVj8KsIUcIYHBIi9Q,1839
150
152
  piccolo/query/methods/__init__.py,sha256=_PfGUdOd6AsKq1sqXeZUHhESHE-e1cNpwFr8Lyz7QoY,421
@@ -212,7 +214,7 @@ tests/apps/migrations/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5
212
214
  tests/apps/migrations/commands/test_base.py,sha256=NgHgVjNd3Hil9eODvW7Ic2D9muTa_grNaH3YpRFfR8I,1829
213
215
  tests/apps/migrations/commands/test_check.py,sha256=hOX_sVk1nfCRfbQ8tJoFEUBFhih9O4QuQLHTp5TQaiY,630
214
216
  tests/apps/migrations/commands/test_clean.py,sha256=lPzLLXhoUyyffY3EQIiyRj-QfP07UVNTha21cEZivfY,1124
215
- tests/apps/migrations/commands/test_forwards_backwards.py,sha256=TjuZz86dEzaUTmcbnRh9lzYp07JXkxsKhJPH8mEbwss,7029
217
+ tests/apps/migrations/commands/test_forwards_backwards.py,sha256=-rwQ3r61eq6lfoMdM-fajK09SAftPn5cri_gSkF2lMk,7107
216
218
  tests/apps/migrations/commands/test_new.py,sha256=dKXOuU6t_6zziHHLvX_JdM_Oiee2Lc7FEuADZsMlNQA,4249
217
219
  tests/apps/migrations/commands/test_migrations/2020-03-31T20-38-22.py,sha256=9pYiFNDi-7TJy5TZ3MeNThttjjcUg6cEQ4J5Yv9wQQ8,601
218
220
  tests/apps/migrations/commands/test_migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -222,7 +224,7 @@ tests/apps/project/commands/test_new.py,sha256=lqeRN9xXXmxJ9Uu0uqkotFsqfkYAexxfF
222
224
  tests/apps/schema/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
223
225
  tests/apps/shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
224
226
  tests/apps/shell/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
225
- tests/apps/shell/commands/test_run.py,sha256=F6BJNcsSTFodz0K1iHOkw4qsXOnGkdtX2s1yQ71y4UM,1132
227
+ tests/apps/shell/commands/test_run.py,sha256=wH3ORQwJ1a02kA-WnZUCNmb0AlwXpRKoTntOZVUZAqI,1170
226
228
  tests/apps/sql_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
227
229
  tests/apps/sql_shell/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
228
230
  tests/apps/sql_shell/commands/test_run.py,sha256=6p0nqCoG_qNLrKeBuHspmer_SrMwEF-vfp9LbPj2W2E,425
@@ -235,7 +237,7 @@ tests/apps/user/commands/test_change_permissions.py,sha256=uVKEiT1EKot3VA2TDETdQ
235
237
  tests/apps/user/commands/test_create.py,sha256=iJ3Tti62rHwvdcTwNXrc5JPam6vR1qxKRdMN456vm3o,2250
236
238
  tests/apps/user/commands/test_list.py,sha256=ipPfGdW6fH7q-Jc7JcYUvlioGmH9GQU0WImZGC2m-XQ,2840
237
239
  tests/columns/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
238
- tests/columns/test_array.py,sha256=eBi3OndotufqW91v7YeqQE3rHEcq_QLaX0ogJaFKETc,6661
240
+ tests/columns/test_array.py,sha256=R6dnUBGcMHi5pVhczI4ydWpXsu2FqRASu6KtkhDWfZo,6660
239
241
  tests/columns/test_base.py,sha256=CTqCNcrqAJTjLXe3MCZgTczrmB3jcVRcOpU4FilpLoQ,3918
240
242
  tests/columns/test_bigint.py,sha256=a0B4y1H02ww5qaW574X2lyenbY6o29ztOhiaqybPC0c,1149
241
243
  tests/columns/test_boolean.py,sha256=kDESp6FnRtSZhuqIu0dBRwKMSpS5TFbbs3sz2MyZSs8,1720
@@ -267,7 +269,7 @@ tests/columns/m2m/test_m2m.py,sha256=LtNsHQ8xAzBFLiZVZhWEB56zu25FnaWtzJ62FZH3heI
267
269
  tests/columns/m2m/test_m2m_schema.py,sha256=oxu7eAjFFpDjnq9Eq-5OTNmlnsEIMFWx18OItfpVs-s,339
268
270
  tests/conf/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
269
271
  tests/conf/example.py,sha256=K8sTttLpEac8rQlOLDY500IGkHj3P3NoyFbCMnT1EqY,347
270
- tests/conf/test_apps.py,sha256=PrU4SRY0HvADGre5pMpALGmbWxPnydBug5ejSYf1e88,8461
272
+ tests/conf/test_apps.py,sha256=aUKH74siXYlrxrjwPMUQi3Xm1LWK9PGh-lulSTwwGsk,8623
271
273
  tests/engine/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
272
274
  tests/engine/test_extra_nodes.py,sha256=xW5gflHzM6ou26DqRSAZoaAbYVzF1IuMkW3vzNmB954,1298
273
275
  tests/engine/test_logging.py,sha256=VLf9A3QuoV7OhV8lttLDB4gzZemnG63kSr-Uyan005U,1287
@@ -283,7 +285,7 @@ tests/example_apps/mega/piccolo_migrations/2021-09-20T21-23-25-698988.py,sha256=
283
285
  tests/example_apps/mega/piccolo_migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
284
286
  tests/example_apps/music/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
285
287
  tests/example_apps/music/piccolo_app.py,sha256=a3RVnqNwb4o74G1c0eEm1zbimilTXZlmy--2PkLmS5I,361
286
- tests/example_apps/music/tables.py,sha256=5Rp_qatvr3eWW86mYyOei2Rb34KsvER_yD0pVqT7OXw,2399
288
+ tests/example_apps/music/tables.py,sha256=uMM7QeFOeWJdRcgwZD7SZRj7953u1s5yn-G1pAHoBpw,2595
287
289
  tests/example_apps/music/tables_detailed.py,sha256=1US-6XO5aipmldAqF_ughIH8ju8i_010tKfqEu_TCeU,2240
288
290
  tests/query/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
289
291
  tests/query/test_await.py,sha256=imGazmG0l4qilveNPwsxvYQogFJtos4YB8N9iggPEFU,412
@@ -316,7 +318,7 @@ tests/table/test_join.py,sha256=Ukgvjc8NweBGHM7fVFytGQYG9P9thRaMeEvWXYs2Qes,1591
316
318
  tests/table/test_join_on.py,sha256=cdAV39JwHi0kIas2p9cw7mcsUv6mKLZD--_SUA0zLfI,2771
317
319
  tests/table/test_metaclass.py,sha256=pMv0PHh-2a9p74bweQXCXnq1OFsJ7Gk0uWRFdCTMf58,4123
318
320
  tests/table/test_objects.py,sha256=bir86ks-Ngy8x9Eu9bekOrh6twBYdEkIgTdbBWY6x9s,8187
319
- tests/table/test_output.py,sha256=_9DydB4bt8GOtzgx7xYrAs6KG8EwRTcZ45EaAHMdEBk,3049
321
+ tests/table/test_output.py,sha256=ZnpPbgVp79JcB6E_ooWQxOpOlhkwNUlMxC-1LSIEc2Y,4304
320
322
  tests/table/test_raw.py,sha256=9PTvYngQi41nYd5lKzkJdTqsEcwrdOXcvZjq-W26CwQ,1683
321
323
  tests/table/test_ref.py,sha256=eYNRnYHzNMXuMbV3B1ca5EidpIg4500q6hr1ccuVaso,269
322
324
  tests/table/test_refresh.py,sha256=ZXGLGHeMZcWnhZPB4eCasv1RkojPt6nUbxaE7WlyJbo,2804
@@ -348,9 +350,9 @@ tests/utils/test_sql_values.py,sha256=vzxRmy16FfLZPH-sAQexBvsF9MXB8n4smr14qoEOS5
348
350
  tests/utils/test_sync.py,sha256=9ytVo56y2vPQePvTeIi9lHIouEhWJbodl1TmzkGFrSo,799
349
351
  tests/utils/test_table_reflection.py,sha256=SIzuat-IpcVj1GCFyOWKShI8YkhdOPPFH7qVrvfyPNE,3794
350
352
  tests/utils/test_warnings.py,sha256=NvSC_cvJ6uZcwAGf1m-hLzETXCqprXELL8zg3TNLVMw,269
351
- piccolo-1.5.0.dist-info/LICENSE,sha256=zFIpi-16uIJ420UMIG75NU0JbDBykvrdnXcj5U_EYBI,1059
352
- piccolo-1.5.0.dist-info/METADATA,sha256=1gdEVjHiwVLu0D6JAY_7FMD8mHuSPyZMHxJVX0BmuqI,5149
353
- piccolo-1.5.0.dist-info/WHEEL,sha256=00yskusixUoUt5ob_CiUp6LsnN5lqzTJpoqOFg_FVIc,92
354
- piccolo-1.5.0.dist-info/entry_points.txt,sha256=SJPHET4Fi1bN5F3WqcKkv9SClK3_F1I7m4eQjk6AFh0,46
355
- piccolo-1.5.0.dist-info/top_level.txt,sha256=-SR74VGbk43VoPy1HH-mHm97yoGukLK87HE5kdBW6qM,24
356
- piccolo-1.5.0.dist-info/RECORD,,
353
+ piccolo-1.5.2.dist-info/LICENSE,sha256=zFIpi-16uIJ420UMIG75NU0JbDBykvrdnXcj5U_EYBI,1059
354
+ piccolo-1.5.2.dist-info/METADATA,sha256=UFmYPf1eC7pCBuoNrO9uMFQaEbNuGC3tvNPT61-dS4I,5177
355
+ piccolo-1.5.2.dist-info/WHEEL,sha256=00yskusixUoUt5ob_CiUp6LsnN5lqzTJpoqOFg_FVIc,92
356
+ piccolo-1.5.2.dist-info/entry_points.txt,sha256=SJPHET4Fi1bN5F3WqcKkv9SClK3_F1I7m4eQjk6AFh0,46
357
+ piccolo-1.5.2.dist-info/top_level.txt,sha256=-SR74VGbk43VoPy1HH-mHm97yoGukLK87HE5kdBW6qM,24
358
+ piccolo-1.5.2.dist-info/RECORD,,
@@ -13,6 +13,7 @@ from tests.base import engines_only
13
13
  from tests.example_apps.music.tables import (
14
14
  Band,
15
15
  Concert,
16
+ Instrument,
16
17
  Manager,
17
18
  Poster,
18
19
  RecordingStudio,
@@ -33,6 +34,7 @@ TABLE_CLASSES: t.List[t.Type[Table]] = [
33
34
  Poster,
34
35
  Shirt,
35
36
  RecordingStudio,
37
+ Instrument,
36
38
  ]
37
39
 
38
40
 
@@ -211,6 +213,7 @@ class TestForwardsBackwards(TestCase):
211
213
  "2021-07-25T22:38:48:009306",
212
214
  "2021-09-06T13:58:23:024723",
213
215
  "2021-11-13T14:01:46:114725",
216
+ "2024-05-28T23:15:41:018844",
214
217
  ],
215
218
  )
216
219
 
@@ -20,6 +20,7 @@ class TestRun(TestCase):
20
20
  call("Importing music tables:"),
21
21
  call("- Band"),
22
22
  call("- Concert"),
23
+ call("- Instrument"),
23
24
  call("- Manager"),
24
25
  call("- Poster"),
25
26
  call("- RecordingStudio"),
@@ -213,7 +213,6 @@ class TestGetDimensions(TestCase):
213
213
 
214
214
 
215
215
  class TestGetInnerValueType(TestCase):
216
-
217
216
  def test_get_inner_value_type(self):
218
217
  """
219
218
  Make sure that `_get_inner_value_type` returns the correct base type.
tests/conf/test_apps.py CHANGED
@@ -9,6 +9,7 @@ from tests.example_apps.mega.tables import MegaTable, SmallTable
9
9
  from tests.example_apps.music.tables import (
10
10
  Band,
11
11
  Concert,
12
+ Instrument,
12
13
  Manager,
13
14
  Poster,
14
15
  RecordingStudio,
@@ -113,6 +114,7 @@ class TestTableFinder(TestCase):
113
114
  [
114
115
  "Band",
115
116
  "Concert",
117
+ "Instrument",
116
118
  "Manager",
117
119
  "Poster",
118
120
  "RecordingStudio",
@@ -139,6 +141,7 @@ class TestTableFinder(TestCase):
139
141
  [
140
142
  "Band",
141
143
  "Concert",
144
+ "Instrument",
142
145
  "Manager",
143
146
  "Poster",
144
147
  "RecordingStudio",
@@ -182,6 +185,7 @@ class TestTableFinder(TestCase):
182
185
  [
183
186
  "Band",
184
187
  "Concert",
188
+ "Instrument",
185
189
  "Manager",
186
190
  "RecordingStudio",
187
191
  "Shirt",
@@ -228,6 +232,7 @@ class TestFinder(TestCase):
228
232
  [
229
233
  Band,
230
234
  Concert,
235
+ Instrument,
231
236
  Manager,
232
237
  MegaTable,
233
238
  Poster,
@@ -247,6 +252,7 @@ class TestFinder(TestCase):
247
252
  [
248
253
  Band,
249
254
  Concert,
255
+ Instrument,
250
256
  Manager,
251
257
  Poster,
252
258
  RecordingStudio,
@@ -115,3 +115,13 @@ class RecordingStudio(Table):
115
115
  id: Serial
116
116
  facilities = JSON()
117
117
  facilities_b = JSONB()
118
+
119
+
120
+ class Instrument(Table):
121
+ """
122
+ Used for testing foreign keys to a table with a JSON column.
123
+ """
124
+
125
+ id: Serial
126
+ name = Varchar()
127
+ recording_studio = ForeignKey(RecordingStudio)
@@ -1,8 +1,9 @@
1
1
  import json
2
2
  from unittest import TestCase
3
3
 
4
- from tests.base import DBTestCase, engine_is
5
- from tests.example_apps.music.tables import Band, RecordingStudio
4
+ from piccolo.table import create_db_tables_sync, drop_db_tables_sync
5
+ from tests.base import DBTestCase
6
+ from tests.example_apps.music.tables import Band, Instrument, RecordingStudio
6
7
 
7
8
 
8
9
  class TestOutputList(DBTestCase):
@@ -32,51 +33,102 @@ class TestOutputJSON(DBTestCase):
32
33
 
33
34
 
34
35
  class TestOutputLoadJSON(TestCase):
36
+ tables = [RecordingStudio, Instrument]
37
+ json = {"a": 123}
38
+
35
39
  def setUp(self):
36
- RecordingStudio.create_table().run_sync()
40
+ create_db_tables_sync(*self.tables)
41
+
42
+ recording_studio = RecordingStudio(
43
+ {
44
+ RecordingStudio.facilities: self.json,
45
+ RecordingStudio.facilities_b: self.json,
46
+ }
47
+ )
48
+ recording_studio.save().run_sync()
49
+
50
+ instrument = Instrument(
51
+ {
52
+ Instrument.recording_studio: recording_studio,
53
+ Instrument.name: "Piccolo",
54
+ }
55
+ )
56
+ instrument.save().run_sync()
37
57
 
38
58
  def tearDown(self):
39
- RecordingStudio.alter().drop_table().run_sync()
59
+ drop_db_tables_sync(*self.tables)
40
60
 
41
61
  def test_select(self):
42
- json = {"a": 123}
43
-
44
- RecordingStudio(facilities=json, facilities_b=json).save().run_sync()
45
-
46
- results = RecordingStudio.select().output(load_json=True).run_sync()
47
-
48
- if engine_is("cockroach"):
49
- self.assertEqual(
50
- results,
51
- [
52
- {
53
- "id": results[0]["id"],
54
- "facilities": {"a": 123},
55
- "facilities_b": {"a": 123},
56
- }
57
- ],
62
+ results = (
63
+ RecordingStudio.select(
64
+ RecordingStudio.facilities, RecordingStudio.facilities_b
58
65
  )
59
- else:
60
- self.assertEqual(
61
- results,
62
- [
63
- {
64
- "id": 1,
65
- "facilities": {"a": 123},
66
- "facilities_b": {"a": 123},
67
- }
68
- ],
66
+ .output(load_json=True)
67
+ .run_sync()
68
+ )
69
+
70
+ self.assertEqual(
71
+ results,
72
+ [
73
+ {
74
+ "facilities": self.json,
75
+ "facilities_b": self.json,
76
+ }
77
+ ],
78
+ )
79
+
80
+ def test_join(self):
81
+ """
82
+ Make sure it works correctly when the JSON column is on a joined table.
83
+
84
+ https://github.com/piccolo-orm/piccolo/issues/1001
85
+
86
+ """
87
+ results = (
88
+ Instrument.select(
89
+ Instrument.name,
90
+ Instrument.recording_studio._.facilities,
69
91
  )
92
+ .output(load_json=True)
93
+ .run_sync()
94
+ )
70
95
 
71
- def test_objects(self):
72
- json = {"a": 123}
96
+ self.assertEqual(
97
+ results,
98
+ [
99
+ {
100
+ "name": "Piccolo",
101
+ "recording_studio.facilities": self.json,
102
+ }
103
+ ],
104
+ )
73
105
 
74
- RecordingStudio(facilities=json, facilities_b=json).save().run_sync()
106
+ def test_join_with_alias(self):
107
+ results = (
108
+ Instrument.select(
109
+ Instrument.name,
110
+ Instrument.recording_studio._.facilities.as_alias(
111
+ "facilities"
112
+ ),
113
+ )
114
+ .output(load_json=True)
115
+ .run_sync()
116
+ )
75
117
 
76
- results = RecordingStudio.objects().output(load_json=True).run_sync()
118
+ self.assertEqual(
119
+ results,
120
+ [
121
+ {
122
+ "name": "Piccolo",
123
+ "facilities": self.json,
124
+ }
125
+ ],
126
+ )
77
127
 
78
- self.assertEqual(results[0].facilities, json)
79
- self.assertEqual(results[0].facilities_b, json)
128
+ def test_objects(self):
129
+ results = RecordingStudio.objects().output(load_json=True).run_sync()
130
+ self.assertEqual(results[0].facilities, self.json)
131
+ self.assertEqual(results[0].facilities_b, self.json)
80
132
 
81
133
 
82
134
  class TestOutputNested(DBTestCase):