piccolo 1.23.0__py3-none-any.whl → 1.24.1__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.1"
@@ -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:
@@ -70,6 +70,7 @@ class TimestampCustom(Default):
70
70
  month: int = 1,
71
71
  day: int = 1,
72
72
  hour: int = 0,
73
+ minute: int = 0,
73
74
  second: int = 0,
74
75
  microsecond: int = 0,
75
76
  ):
@@ -77,6 +78,7 @@ class TimestampCustom(Default):
77
78
  self.month = month
78
79
  self.day = day
79
80
  self.hour = hour
81
+ self.minute = minute
80
82
  self.second = second
81
83
  self.microsecond = microsecond
82
84
 
@@ -87,6 +89,7 @@ class TimestampCustom(Default):
87
89
  month=self.month,
88
90
  day=self.day,
89
91
  hour=self.hour,
92
+ minute=self.minute,
90
93
  second=self.second,
91
94
  microsecond=self.microsecond,
92
95
  )
@@ -113,8 +116,9 @@ class TimestampCustom(Default):
113
116
  return cls(
114
117
  year=instance.year,
115
118
  month=instance.month,
116
- day=instance.month,
119
+ day=instance.day,
117
120
  hour=instance.hour,
121
+ minute=instance.minute,
118
122
  second=instance.second,
119
123
  microsecond=instance.microsecond,
120
124
  )
@@ -47,6 +47,7 @@ class TimestamptzCustom(TimestampCustom):
47
47
  month=self.month,
48
48
  day=self.day,
49
49
  hour=self.hour,
50
+ minute=self.minute,
50
51
  second=self.second,
51
52
  microsecond=self.microsecond,
52
53
  tzinfo=datetime.timezone.utc,
@@ -59,8 +60,9 @@ class TimestamptzCustom(TimestampCustom):
59
60
  return cls(
60
61
  year=instance.year,
61
62
  month=instance.month,
62
- day=instance.month,
63
+ day=instance.day,
63
64
  hour=instance.hour,
65
+ minute=instance.minute,
64
66
  second=instance.second,
65
67
  microsecond=instance.microsecond,
66
68
  )
@@ -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
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: piccolo
3
- Version: 1.23.0
3
+ Version: 1.24.1
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
@@ -54,6 +54,7 @@ Dynamic: description
54
54
  Dynamic: description-content-type
55
55
  Dynamic: home-page
56
56
  Dynamic: license
57
+ Dynamic: license-file
57
58
  Dynamic: project-url
58
59
  Dynamic: provides-extra
59
60
  Dynamic: requires-dist
@@ -1,4 +1,4 @@
1
- piccolo/__init__.py,sha256=GQnDEg6DEILG11IPb7zmEaAIEhC_p4YXBMT2yPZ7TN4,23
1
+ piccolo/__init__.py,sha256=fqbFeUPVIVzt-2TqaZSPsISdBRr5iqLv8pFlnMYP1pU,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
@@ -134,8 +134,8 @@ piccolo/columns/defaults/base.py,sha256=z_ZgtSFbLuwqdYdI7dr2n1SeyTJ7M4Ee4Ki7eRaB
134
134
  piccolo/columns/defaults/date.py,sha256=Duuyi-QJ9Rr72aJkCNnjyO1CJBE-inZNGKnyV8tbLLE,2517
135
135
  piccolo/columns/defaults/interval.py,sha256=ypaQpgDm1AL0WTMFEgKCt0I-e9ADUYdRRSBl65IJdiw,1987
136
136
  piccolo/columns/defaults/time.py,sha256=2e0SDjl9_Mrw2YUeLFXDDYhmlC9Qjek3MkhvmWKQFH0,2417
137
- piccolo/columns/defaults/timestamp.py,sha256=3Ng_LJ76nic-3j_AIzZfUvj3djIFRVkps98w1b_2lUM,3565
138
- piccolo/columns/defaults/timestamptz.py,sha256=RMw9wW20NbvaG_HY-0amBRuD-OLde4at_xQCf0D8NE4,2096
137
+ piccolo/columns/defaults/timestamp.py,sha256=O7SDldwDku8Bd3n0JPxUSzYo7FDYrgWgdxI-0o4sOvk,3685
138
+ piccolo/columns/defaults/timestamptz.py,sha256=9xCpIbxH4gy8UY8Ucc_OGwN9hOOzXz7PbXKaNQx6UNs,2162
139
139
  piccolo/columns/defaults/uuid.py,sha256=zBBaXlUsDTKcxRFDWwqgpiDRrYd7ptxC_hf7UqYhRjY,470
140
140
  piccolo/columns/operators/__init__.py,sha256=fIIm309C7ddqrP-M9oLlfhcZEM4Fx5B203QMzBm0OpM,310
141
141
  piccolo/columns/operators/base.py,sha256=UfaqPd-ieqydrjhvcGYiwHMOKs199tTiT1gFE15DZzo,34
@@ -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
@@ -199,6 +199,7 @@ piccolo/utils/sync.py,sha256=j9Abkxn5HHS6HyvfpMzb1zV_teTkFHVhaIxu9rrSwSU,819
199
199
  piccolo/utils/warnings.py,sha256=ONrurw3HVCClUuHnpenMjg45dcFesrXqMgG9ifgP4_8,1247
200
200
  piccolo/utils/graphlib/__init__.py,sha256=SUJ5Yh7LiRun3nkBuLUSVmGNHF6fANrxSoYan0mtYB0,200
201
201
  piccolo/utils/graphlib/_graphlib.py,sha256=9FNGDSmTIEAk86FktniCe_J2yXjSE_sRZHDBAJJAUOw,9677
202
+ piccolo-1.24.1.dist-info/licenses/LICENSE,sha256=zFIpi-16uIJ420UMIG75NU0JbDBykvrdnXcj5U_EYBI,1059
202
203
  profiling/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
203
204
  profiling/run_profile.py,sha256=264qsSFu93NTpExePnKQ9GkcN5fiuRBQ72WOSt0ZHck,829
204
205
  tests/apps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -243,7 +244,7 @@ tests/apps/shell/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJW
243
244
  tests/apps/shell/commands/test_run.py,sha256=wH3ORQwJ1a02kA-WnZUCNmb0AlwXpRKoTntOZVUZAqI,1170
244
245
  tests/apps/sql_shell/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
245
246
  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
247
+ tests/apps/sql_shell/commands/test_run.py,sha256=MDfuJdgOSEMAEXtBQYWx2N31tRHgKPPQNUpVCRTPyu8,1033
247
248
  tests/apps/tester/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
248
249
  tests/apps/user/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
249
250
  tests/apps/user/test_tables.py,sha256=5ImGAWpIKxlqweGeJRMiVOHaBJxRwSzsp3GZ7x6lzCo,9807
@@ -262,7 +263,7 @@ tests/columns/test_choices.py,sha256=q8TLe7nvGERXyGO_XEryEBR-DuWwFY1jPpscsrXjdXo
262
263
  tests/columns/test_combination.py,sha256=BuBwR7k5X1EkOWraZpjqU6gvtb6ow_k-7N1KQBiW2RA,1681
263
264
  tests/columns/test_date.py,sha256=QLC6kJMQwM-1mbUP4ksJVM7P8WwjzGZyynH3rHHdSew,1030
264
265
  tests/columns/test_db_column_name.py,sha256=0wz6y4GNGy4nhMdHmYzEnChQGpK2UhWFFKrnmmML3Mk,9027
265
- tests/columns/test_defaults.py,sha256=rwlU1fXt3cCl7C51eLlZXqgWkE-K5W0pHvTrwkAKyCo,2896
266
+ tests/columns/test_defaults.py,sha256=SUY00eMpYSmEyl6UvGRjd_HwW5wC_tkHrwCDcYzlkUQ,3872
266
267
  tests/columns/test_double_precision.py,sha256=7rhcSfDkb2fBh_zEG4UGwD_GW1sy6U9-8NooHuCS09Q,544
267
268
  tests/columns/test_get_sql_value.py,sha256=mKgsInN374jzV99y9mg_ZiG-AvnJgz36SZi89xL7RZM,1768
268
269
  tests/columns/test_integer.py,sha256=IcIQq0gF29gTxLY3CJuXtE13-20emqisY2wRQsu80F4,772
@@ -344,7 +345,7 @@ tests/table/test_insert.py,sha256=c7hJ1SsTiW43l_Z5KHSN3894ICzttOAsTfWN9rUOl0k,13
344
345
  tests/table/test_join.py,sha256=Ukgvjc8NweBGHM7fVFytGQYG9P9thRaMeEvWXYs2Qes,15910
345
346
  tests/table/test_join_on.py,sha256=cdAV39JwHi0kIas2p9cw7mcsUv6mKLZD--_SUA0zLfI,2771
346
347
  tests/table/test_metaclass.py,sha256=pMv0PHh-2a9p74bweQXCXnq1OFsJ7Gk0uWRFdCTMf58,4123
347
- tests/table/test_objects.py,sha256=bir86ks-Ngy8x9Eu9bekOrh6twBYdEkIgTdbBWY6x9s,8187
348
+ tests/table/test_objects.py,sha256=ptbeIICOfZ2-Fl6K_Llo1SKIyQ5ngUZ-rZtgll5cMWM,9047
348
349
  tests/table/test_output.py,sha256=ZnpPbgVp79JcB6E_ooWQxOpOlhkwNUlMxC-1LSIEc2Y,4304
349
350
  tests/table/test_raw.py,sha256=9PTvYngQi41nYd5lKzkJdTqsEcwrdOXcvZjq-W26CwQ,1683
350
351
  tests/table/test_ref.py,sha256=eYNRnYHzNMXuMbV3B1ca5EidpIg4500q6hr1ccuVaso,269
@@ -379,9 +380,8 @@ tests/utils/test_sql_values.py,sha256=vzxRmy16FfLZPH-sAQexBvsF9MXB8n4smr14qoEOS5
379
380
  tests/utils/test_sync.py,sha256=9ytVo56y2vPQePvTeIi9lHIouEhWJbodl1TmzkGFrSo,799
380
381
  tests/utils/test_table_reflection.py,sha256=SIzuat-IpcVj1GCFyOWKShI8YkhdOPPFH7qVrvfyPNE,3794
381
382
  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,,
383
+ piccolo-1.24.1.dist-info/METADATA,sha256=E-iRyVUdWPUJprZz1ofdSYkE9OPTLlCQAi_lguMXQlg,5531
384
+ piccolo-1.24.1.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
385
+ piccolo-1.24.1.dist-info/entry_points.txt,sha256=SJPHET4Fi1bN5F3WqcKkv9SClK3_F1I7m4eQjk6AFh0,46
386
+ piccolo-1.24.1.dist-info/top_level.txt,sha256=-SR74VGbk43VoPy1HH-mHm97yoGukLK87HE5kdBW6qM,24
387
+ piccolo-1.24.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.8.0)
2
+ Generator: setuptools (77.0.3)
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"]
@@ -22,6 +22,8 @@ from piccolo.columns.column_types import (
22
22
  TimestampNow,
23
23
  Varchar,
24
24
  )
25
+ from piccolo.columns.defaults.timestamp import TimestampCustom
26
+ from piccolo.columns.defaults.timestamptz import TimestamptzCustom
25
27
  from piccolo.table import Table
26
28
 
27
29
 
@@ -98,3 +100,35 @@ class TestDefaults(TestCase):
98
100
  ForeignKey(references=MyTable, default=1)
99
101
  with self.assertRaises(ValueError):
100
102
  ForeignKey(references=MyTable, default="hello world")
103
+
104
+
105
+ class TestDatetime(TestCase):
106
+
107
+ def test_datetime(self):
108
+ """
109
+ Make sure we can create a `TimestampCustom` / `TimestamptzCustom` from
110
+ a datetime, and then convert it back into the same datetime again.
111
+
112
+ https://github.com/piccolo-orm/piccolo/issues/1169
113
+
114
+ """
115
+ datetime_obj = datetime.datetime(
116
+ year=2025,
117
+ month=1,
118
+ day=30,
119
+ hour=12,
120
+ minute=10,
121
+ second=15,
122
+ microsecond=100,
123
+ )
124
+
125
+ self.assertEqual(
126
+ TimestampCustom.from_datetime(datetime_obj).datetime,
127
+ datetime_obj,
128
+ )
129
+
130
+ datetime_obj = datetime_obj.astimezone(tz=datetime.timezone.utc)
131
+ self.assertEqual(
132
+ TimestamptzCustom.from_datetime(datetime_obj).datetime,
133
+ datetime_obj,
134
+ )
@@ -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
+ )