piccolo 1.23.0__py3-none-any.whl → 1.24.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 CHANGED
@@ -1 +1 @@
1
- __VERSION__ = "1.23.0"
1
+ __VERSION__ = "1.24.0"
@@ -28,24 +28,23 @@ def run() -> None:
28
28
 
29
29
  args = ["psql"]
30
30
 
31
- host = engine.config.get("host")
32
- port = engine.config.get("port")
33
- user = engine.config.get("user")
34
- password = engine.config.get("password")
35
- database = engine.config.get("database")
31
+ config = engine.config
36
32
 
37
- if user:
38
- args += ["-U", user]
39
- if host:
40
- args += ["-h", host]
41
- if port:
42
- args += ["-p", str(port)]
43
- if database:
44
- args += [database]
33
+ if dsn := config.get("dsn"):
34
+ args += [dsn]
35
+ else:
36
+ if user := config.get("user"):
37
+ args += ["-U", user]
38
+ if host := config.get("host"):
39
+ args += ["-h", host]
40
+ if port := config.get("port"):
41
+ args += ["-p", str(port)]
42
+ if database := config.get("database"):
43
+ args += [database]
45
44
 
46
45
  sigint_handler = signal.getsignal(signal.SIGINT)
47
46
  subprocess_env = os.environ.copy()
48
- if password:
47
+ if password := config.get("password"):
49
48
  subprocess_env["PGPASSWORD"] = str(password)
50
49
  try:
51
50
  # Allow SIGINT to pass to psql to abort queries.
@@ -202,7 +202,9 @@ class BaseUser(Table, tablename="piccolo_user"):
202
202
  The id of the user if a match is found, otherwise ``None``.
203
203
 
204
204
  """
205
- if len(username) > cls.username.length:
205
+ if (max_username_length := cls.username.length) and len(
206
+ username
207
+ ) > max_username_length:
206
208
  logger.warning("Excessively long username provided.")
207
209
  return None
208
210
 
@@ -315,7 +315,7 @@ class Varchar(Column):
315
315
 
316
316
  def __init__(
317
317
  self,
318
- length: int = 255,
318
+ length: t.Optional[int] = 255,
319
319
  default: t.Union[str, Enum, t.Callable[[], str], None] = "",
320
320
  **kwargs,
321
321
  ) -> None:
@@ -65,22 +65,20 @@ class GetOrCreate(
65
65
  instance._was_created = False
66
66
  return instance
67
67
 
68
- instance = self.table_class(_data=self.defaults)
68
+ data = {**self.defaults}
69
69
 
70
70
  # If it's a complex `where`, there can be several column values to
71
71
  # extract e.g. (Band.name == 'Pythonistas') & (Band.popularity == 1000)
72
72
  if isinstance(self.where, Where):
73
- setattr(
74
- instance,
75
- self.where.column._meta.name, # type: ignore
76
- self.where.value, # type: ignore
77
- )
73
+ data[self.where.column] = self.where.value
78
74
  elif isinstance(self.where, And):
79
75
  for column, value in self.where.get_column_values().items():
80
76
  if len(column._meta.call_chain) == 0:
81
77
  # Make sure we only set the value if the column belongs
82
78
  # to this table.
83
- setattr(instance, column._meta.name, value)
79
+ data[column] = value
80
+
81
+ instance = self.table_class(_data=data)
84
82
 
85
83
  await instance.save().run(node=node, in_pool=in_pool)
86
84
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: piccolo
3
- Version: 1.23.0
3
+ Version: 1.24.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=GQnDEg6DEILG11IPb7zmEaAIEhC_p4YXBMT2yPZ7TN4,23
1
+ piccolo/__init__.py,sha256=uyuLf5Q7X3vuYYBK0p5G67YV-evr3rtlsYxNysnS3W8,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
@@ -103,14 +103,14 @@ piccolo/apps/shell/commands/run.py,sha256=BiGMnM0wGKNvZOklgQeU_ZhBYWFxtsTQuvVHdo
103
103
  piccolo/apps/sql_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
104
104
  piccolo/apps/sql_shell/piccolo_app.py,sha256=uFuMQIPLSMYi7y5x3wG1LPqGmEkwC-dYlmLTKrBaUQQ,221
105
105
  piccolo/apps/sql_shell/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
106
- piccolo/apps/sql_shell/commands/run.py,sha256=PdBoeA-fsvfLpjwRXc9_MB1q_u0UKR-EzpgFIonwIHc,2060
106
+ piccolo/apps/sql_shell/commands/run.py,sha256=mOt0kuJ_-QhKXrlt0Ceicx4JxxCLlK6OwUyB_HQpLiI,2097
107
107
  piccolo/apps/tester/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
108
108
  piccolo/apps/tester/piccolo_app.py,sha256=LAAzW3SdVKZjvVXpBxwprYxV0rJbeDD3CB5JpRmHm8k,225
109
109
  piccolo/apps/tester/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
110
110
  piccolo/apps/tester/commands/run.py,sha256=phFxim2ogARAviW-YT11y9F-L5SJxSioAIepUzQeAWU,2431
111
111
  piccolo/apps/user/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
112
112
  piccolo/apps/user/piccolo_app.py,sha256=yfw1J9FEnBWdgGdUdNMnqp06Wzm5_s9TO2r5KLchrLM,842
113
- piccolo/apps/user/tables.py,sha256=KgPqONdl1SDV-3cGq5aS-za_v_5_TGHQqNFYXF0M3Jw,9082
113
+ piccolo/apps/user/tables.py,sha256=QD8FD3qhtBqfFAkAMjQVqTnxrPmwa_V2uzVzk16eRaU,9153
114
114
  piccolo/apps/user/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
115
115
  piccolo/apps/user/commands/change_password.py,sha256=F7mlhtTUY7uENSK8vds5oibIDJTz7QBQdrl7EB-lF9Q,649
116
116
  piccolo/apps/user/commands/change_permissions.py,sha256=LScsKJUMJqIi54cZ1SgS9Wb356KB0t7smu94FDXLfVk,1463
@@ -123,7 +123,7 @@ piccolo/apps/user/piccolo_migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeu
123
123
  piccolo/columns/__init__.py,sha256=OYhO_n9anMiU9nL-K6ATq9FhAtm8RyMpqYQ7fTVbhxI,1120
124
124
  piccolo/columns/base.py,sha256=_bg9yMWjMwE76Z7RDqi9iYSmtRuFx5bkx9uYJsFHKjQ,32487
125
125
  piccolo/columns/choices.py,sha256=-HNQuk9vMmVZIPZ5PMeXGTfr23o4nzKPSAkvcG1k0y8,723
126
- piccolo/columns/column_types.py,sha256=XVI6qA_qsP1BD6bqVqQdj7a8dldoYz4VgOPI-wW696I,84747
126
+ piccolo/columns/column_types.py,sha256=Wo6g14aL1vpOFugsY-6n-q6JUJaKih-cIn9NBp-f3fI,84759
127
127
  piccolo/columns/combination.py,sha256=vMXC2dfY7pvnCFhsT71XFVyb4gdQzfRsCMaiduu04Ss,6900
128
128
  piccolo/columns/indexes.py,sha256=NfNok3v_791jgDlN28KmhP9ZCjl6031BXmjxV3ovXJk,372
129
129
  piccolo/columns/m2m.py,sha256=QMeSOnm4DT2cG9U5jC6sOZ6z9DxCWwDyZMSqk0wR2q4,14682
@@ -172,7 +172,7 @@ piccolo/query/methods/drop_index.py,sha256=5x3vHpoOmQ1SMhj6L7snKXX6M9l9j1E1PFSO6
172
172
  piccolo/query/methods/exists.py,sha256=lTMjtrFPFygZmaPV3sfQKXc3K0sVqJ2S6PDc3fRK6YQ,1203
173
173
  piccolo/query/methods/indexes.py,sha256=J-QUqaBJwpgahskUH0Cu0Mq7zEKcfVAtDsUVIVX-C4c,943
174
174
  piccolo/query/methods/insert.py,sha256=ssLJ_wn08KnOwwr7t-VILyn1P4hrvM63CfPIcAJWT5k,4701
175
- piccolo/query/methods/objects.py,sha256=BfCOIbNMj7FWkmK5STaINkfDFmwzZvDZi60jCumjs1o,15627
175
+ piccolo/query/methods/objects.py,sha256=wK3poKXVVTpjFgpVfmumVn9q8Qiqz0PZ4ukm7Ih-CGw,15511
176
176
  piccolo/query/methods/raw.py,sha256=wQWR8b-yA_Gr-5lqRMZe9BOAAMBAw8CqTx37qVYvM1A,987
177
177
  piccolo/query/methods/refresh.py,sha256=wg1zghKfwz-VmqK4uWa4GNMiDtK-skTqow591Hb3ONM,5854
178
178
  piccolo/query/methods/select.py,sha256=41OW-DIE_wr5VdxSusMKNT2aUhzQsCwK2Qh1XqgXHg0,22424
@@ -243,7 +243,7 @@ tests/apps/shell/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
243
243
  tests/apps/shell/commands/test_run.py,sha256=wH3ORQwJ1a02kA-WnZUCNmb0AlwXpRKoTntOZVUZAqI,1170
244
244
  tests/apps/sql_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
245
245
  tests/apps/sql_shell/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
246
- tests/apps/sql_shell/commands/test_run.py,sha256=6p0nqCoG_qNLrKeBuHspmer_SrMwEF-vfp9LbPj2W2E,425
246
+ tests/apps/sql_shell/commands/test_run.py,sha256=MDfuJdgOSEMAEXtBQYWx2N31tRHgKPPQNUpVCRTPyu8,1033
247
247
  tests/apps/tester/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
248
248
  tests/apps/user/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
249
249
  tests/apps/user/test_tables.py,sha256=5ImGAWpIKxlqweGeJRMiVOHaBJxRwSzsp3GZ7x6lzCo,9807
@@ -344,7 +344,7 @@ tests/table/test_insert.py,sha256=c7hJ1SsTiW43l_Z5KHSN3894ICzttOAsTfWN9rUOl0k,13
344
344
  tests/table/test_join.py,sha256=Ukgvjc8NweBGHM7fVFytGQYG9P9thRaMeEvWXYs2Qes,15910
345
345
  tests/table/test_join_on.py,sha256=cdAV39JwHi0kIas2p9cw7mcsUv6mKLZD--_SUA0zLfI,2771
346
346
  tests/table/test_metaclass.py,sha256=pMv0PHh-2a9p74bweQXCXnq1OFsJ7Gk0uWRFdCTMf58,4123
347
- tests/table/test_objects.py,sha256=bir86ks-Ngy8x9Eu9bekOrh6twBYdEkIgTdbBWY6x9s,8187
347
+ tests/table/test_objects.py,sha256=ptbeIICOfZ2-Fl6K_Llo1SKIyQ5ngUZ-rZtgll5cMWM,9047
348
348
  tests/table/test_output.py,sha256=ZnpPbgVp79JcB6E_ooWQxOpOlhkwNUlMxC-1LSIEc2Y,4304
349
349
  tests/table/test_raw.py,sha256=9PTvYngQi41nYd5lKzkJdTqsEcwrdOXcvZjq-W26CwQ,1683
350
350
  tests/table/test_ref.py,sha256=eYNRnYHzNMXuMbV3B1ca5EidpIg4500q6hr1ccuVaso,269
@@ -379,9 +379,9 @@ tests/utils/test_sql_values.py,sha256=vzxRmy16FfLZPH-sAQexBvsF9MXB8n4smr14qoEOS5
379
379
  tests/utils/test_sync.py,sha256=9ytVo56y2vPQePvTeIi9lHIouEhWJbodl1TmzkGFrSo,799
380
380
  tests/utils/test_table_reflection.py,sha256=SIzuat-IpcVj1GCFyOWKShI8YkhdOPPFH7qVrvfyPNE,3794
381
381
  tests/utils/test_warnings.py,sha256=NvSC_cvJ6uZcwAGf1m-hLzETXCqprXELL8zg3TNLVMw,269
382
- piccolo-1.23.0.dist-info/LICENSE,sha256=zFIpi-16uIJ420UMIG75NU0JbDBykvrdnXcj5U_EYBI,1059
383
- piccolo-1.23.0.dist-info/METADATA,sha256=2b_3SG-OwxwIkYypspgkWfZma9DYegZSfEX7OjdVXQw,5509
384
- piccolo-1.23.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
385
- piccolo-1.23.0.dist-info/entry_points.txt,sha256=SJPHET4Fi1bN5F3WqcKkv9SClK3_F1I7m4eQjk6AFh0,46
386
- piccolo-1.23.0.dist-info/top_level.txt,sha256=-SR74VGbk43VoPy1HH-mHm97yoGukLK87HE5kdBW6qM,24
387
- piccolo-1.23.0.dist-info/RECORD,,
382
+ piccolo-1.24.0.dist-info/LICENSE,sha256=zFIpi-16uIJ420UMIG75NU0JbDBykvrdnXcj5U_EYBI,1059
383
+ piccolo-1.24.0.dist-info/METADATA,sha256=Bnqm6WVw_mNMp5G2xHPbJU-bIJTTQgmaiLRlXFaOhKM,5509
384
+ piccolo-1.24.0.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
385
+ piccolo-1.24.0.dist-info/entry_points.txt,sha256=SJPHET4Fi1bN5F3WqcKkv9SClK3_F1I7m4eQjk6AFh0,46
386
+ piccolo-1.24.0.dist-info/top_level.txt,sha256=-SR74VGbk43VoPy1HH-mHm97yoGukLK87HE5kdBW6qM,24
387
+ piccolo-1.24.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (76.0.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -2,13 +2,37 @@ from unittest import TestCase
2
2
  from unittest.mock import MagicMock, patch
3
3
 
4
4
  from piccolo.apps.sql_shell.commands.run import run
5
+ from tests.base import postgres_only, sqlite_only
5
6
 
6
7
 
7
8
  class TestRun(TestCase):
9
+ @postgres_only
8
10
  @patch("piccolo.apps.sql_shell.commands.run.subprocess")
9
- def test_run(self, subprocess: MagicMock):
11
+ def test_psql(self, subprocess: MagicMock):
10
12
  """
11
- A simple test to make sure it executes without raising any exceptions.
13
+ Make sure psql was called correctly.
12
14
  """
13
15
  run()
14
16
  self.assertTrue(subprocess.run.called)
17
+
18
+ assert subprocess.run.call_args.args[0] == [
19
+ "psql",
20
+ "-U",
21
+ "postgres",
22
+ "-h",
23
+ "localhost",
24
+ "-p",
25
+ "5432",
26
+ "piccolo",
27
+ ]
28
+
29
+ @sqlite_only
30
+ @patch("piccolo.apps.sql_shell.commands.run.subprocess")
31
+ def test_sqlite3(self, subprocess: MagicMock):
32
+ """
33
+ Make sure sqlite3 was called correctly.
34
+ """
35
+ run()
36
+ self.assertTrue(subprocess.run.called)
37
+
38
+ assert subprocess.run.call_args.args[0] == ["sqlite3", "test.sqlite"]
@@ -1,3 +1,5 @@
1
+ from piccolo.columns.column_types import ForeignKey
2
+ from piccolo.testing.test_case import AsyncTableTest
1
3
  from tests.base import DBTestCase, engines_only, sqlite_only
2
4
  from tests.example_apps.music.tables import Band, Manager
3
5
 
@@ -268,3 +270,32 @@ class TestGetOrCreate(DBTestCase):
268
270
  self.assertIsInstance(band.manager, Manager)
269
271
  self.assertEqual(band.name, "New Band 2")
270
272
  self.assertEqual(band.manager.name, "Guido")
273
+
274
+
275
+ class BandNotNull(Band, tablename="band"):
276
+ manager = ForeignKey(Manager, null=False)
277
+
278
+
279
+ class TestGetOrCreateNotNull(AsyncTableTest):
280
+
281
+ tables = [BandNotNull, Manager]
282
+
283
+ async def test_not_null(self):
284
+ """
285
+ There was a bug where `get_or_create` would fail for columns with
286
+ `default=None` and `null=False`, even if the value for those columns
287
+ was specified in the where clause.
288
+
289
+ https://github.com/piccolo-orm/piccolo/issues/1152
290
+
291
+ """
292
+
293
+ manager = Manager({Manager.name: "Test"})
294
+ await manager.save()
295
+
296
+ self.assertIsInstance(
297
+ await BandNotNull.objects().get_or_create(
298
+ BandNotNull.manager == manager
299
+ ),
300
+ BandNotNull,
301
+ )