Skip to content

Commit 3def456

Browse files
authored
Merge branch 'piccolo-orm:master' into composite_index
2 parents 9c53f80 + 46b982b commit 3def456

8 files changed

Lines changed: 106 additions & 20 deletions

File tree

CHANGES.rst

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,48 @@
11
Changes
22
=======
33

4+
1.31.0
5+
------
6+
7+
* Added official Postgres 18 support.
8+
* Removed graphlib backport (no longer needed in supported Python versions).
9+
* Improved documentation for column kwargs.
10+
* Updated README to mention other parts of the Piccolo ecosystem (thanks to
11+
@sinisaos for this).
12+
* Table instances can now be compared using the ``==`` operator, and will
13+
return ``True`` if they have the same primary key value (thanks to @aarcex3
14+
and @Skelmis for this).
15+
* Fixed missing import for auto migrations when tables use
16+
``LazyTableReference`` (thanks to @sinisaos for this).
17+
* Improved docs for the auto generated primary key (thanks to @badlydrawnrob
18+
for this).
19+
* Improved ``Table._table_str`` (this is most obvious in the playground, where
20+
the table definitions printed out now show more information - thanks to
21+
@badlydrawnrob for raising this issue).
22+
* Fixed a bug with ``ModelBuilder`` when using ``Array`` columns with
23+
``choices`` defined.
24+
* ``add_m2m`` now returns the id of the joining table row, to match the docs
25+
(thanks to @diklios5768 for reporting this).
26+
* Improved the docs for ``UUID`` columns (what the ``UUID4`` default value
27+
does).
28+
* Moved connection pooling to its own page in the docs.
29+
* Improved the ``on_conflict`` clause - a ``target`` must be specified if
30+
using ``DO UPDATE`` (thanks to @mafuyuuu1 for raising this issue, and
31+
@sinisaos for this fix).
32+
* Changed Esmerald to Ravyn in the ASGI templates (thanks to @sinisaos for
33+
this).
34+
* Fixed a bug with auto migrations when changing a column to a foreign key - an
35+
exception was being raised (thanks to @gsavchuk for raising this issue and
36+
@sinisaos for this fix).
37+
* ``Array(Numeric())`` columns now work with SQLite (thanks to @sinisaos for
38+
this).
39+
* UUID columns now use the built-in ``gen_random_uuid()`` function in Postgres
40+
to generate a default value, instead of using the ``uuid-ossp`` extension
41+
(thanks to @sinisaos for this). See
42+
:ref:`this tutorial <UUIDColumnsMigrationTutorial>` for more details.
43+
44+
-------------------------------------------------------------------------------
45+
446
1.30.0
547
------
648

docs/src/piccolo/engines/sqlite_engine.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,4 +30,4 @@ Production tips
3030
---------------
3131

3232
If you're planning on using SQLite in production with Piccolo, with lots of
33-
concurrent queries, then here are some :ref:`useful tips <UsingSQLitAndAsyncioEffectively>`.
33+
concurrent queries, then here are some :ref:`useful tips <UsingSQLiteAndAsyncioEffectively>`.

docs/src/piccolo/tutorials/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ help you solve common problems:
1313
./fastapi
1414
./avoiding_circular_imports
1515
./moving_table_between_apps
16+
./uuid_columns_in_piccolo_1.31.0

docs/src/piccolo/tutorials/using_sqlite_and_asyncio_effectively.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
.. _UsingSQLitAndAsyncioEffectively:
1+
.. _UsingSQLiteAndAsyncioEffectively:
22

33
Using SQLite and asyncio effectively
44
====================================
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
.. _UUIDColumnsMigrationTutorial:
2+
3+
UUID columns in Piccolo >= 1.31.0
4+
=================================
5+
6+
Prior to ``piccolo==1.31.0``, Postgres
7+
:class:`UUID<piccolo.columns.column_types.UUID>` columns generated their
8+
default values using ``uuid_generate_v4()``, which is part of the
9+
``uuid-ossp`` extension.
10+
11+
In all the versions of Posgres that Piccolo supports, there is now a
12+
``gen_random_uuid()`` function built in, which Piccolo now uses for all new
13+
``UUID`` columns for generating default values in the database.
14+
15+
Your existing ``UUID`` columns will be left alone, and will continue to use the
16+
``uuid-ossp`` extension.
17+
18+
Note that :class:`PostgresEngine<piccolo.engine.postgres.PostgresEngine>` has
19+
an ``extensions`` argument. These are Postgres extensions which Piccolo will
20+
try to enable when starting up. This used to include ``uuid-ossp`` by default,
21+
but this is no longer the case. If you want to maintain the old behaviour,
22+
simply do this:
23+
24+
.. code-block:: python
25+
26+
DB = PostgresEngine(extensions=['uuid-ossp'])
27+
28+
If you want to migrate an existing ``UUID`` column over to use
29+
``gen_random_uuid()`` then run this script:
30+
31+
.. code-block:: sql
32+
33+
ALTER TABLE my_table ALTER COLUMN my_uuid_column SET DEFAULT gen_random_uuid();

piccolo/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__VERSION__ = "1.30.0"
1+
__VERSION__ = "1.31.0"

piccolo/engine/sqlite.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ def serialise(data: list):
105105
if isinstance(item, list):
106106
output.append(serialise(item))
107107
elif isinstance(
108-
item, (datetime.datetime, datetime.time, datetime.date)
108+
item,
109+
(datetime.datetime, datetime.time, datetime.date, Decimal),
109110
):
110111
if adapter := ADAPTERS.get(type(item)):
111112
output.append(adapter(item))
@@ -317,7 +318,7 @@ def convert_M2M_out(value: str) -> list:
317318

318319
# We have special column types for arrays of timestamps etc, as simply loading
319320
# the JSON isn't sufficient.
320-
for column_name in ("TIMESTAMP", "TIMESTAMPTZ", "DATE", "TIME"):
321+
for column_name in ("TIMESTAMP", "TIMESTAMPTZ", "DATE", "TIME", "NUMERIC"):
321322
sqlite3.register_converter(
322323
f"ARRAY_{column_name}",
323324
partial(

tests/columns/test_array.py

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import datetime
2+
from decimal import Decimal
23
from unittest import TestCase
34

45
import pytest
@@ -8,6 +9,7 @@
89
BigInt,
910
Date,
1011
Integer,
12+
Numeric,
1113
Time,
1214
Timestamp,
1315
Timestamptz,
@@ -411,21 +413,23 @@ def test_remove_sqlite(self):
411413

412414

413415
###############################################################################
414-
# Date and time arrays
416+
# Date, time and decimal arrays
415417

416418

417-
class DateTimeArrayTable(Table):
419+
class DateTimeDecimalArrayTable(Table):
418420
date = Array(Date())
419421
time = Array(Time())
420422
timestamp = Array(Timestamp())
421423
timestamptz = Array(Timestamptz())
424+
decimal = Array(Numeric(digits=(5, 2)))
422425
date_nullable = Array(Date(), null=True)
423426
time_nullable = Array(Time(), null=True)
424427
timestamp_nullable = Array(Timestamp(), null=True)
425428
timestamptz_nullable = Array(Timestamptz(), null=True)
429+
decimal_nullable = Array(Numeric(digits=(5, 2)), null=True)
426430

427431

428-
class TestDateTimeArray(TestCase):
432+
class TestDateTimeDecimalArray(TestCase):
429433
"""
430434
Make sure that data can be stored and retrieved when using arrays of
431435
date / time / timestamp.
@@ -436,10 +440,10 @@ class TestDateTimeArray(TestCase):
436440
"""
437441

438442
def setUp(self):
439-
DateTimeArrayTable.create_table().run_sync()
443+
DateTimeDecimalArrayTable.create_table().run_sync()
440444

441445
def tearDown(self):
442-
DateTimeArrayTable.alter().drop_table().run_sync()
446+
DateTimeDecimalArrayTable.alter().drop_table().run_sync()
443447

444448
@engines_only("postgres", "sqlite")
445449
def test_storage(self):
@@ -456,32 +460,37 @@ def test_storage(self):
456460
minute=0,
457461
tzinfo=datetime.timezone.utc,
458462
)
463+
test_decimal = Decimal("50.0")
459464

460-
DateTimeArrayTable(
465+
DateTimeDecimalArrayTable(
461466
{
462-
DateTimeArrayTable.date: [test_date],
463-
DateTimeArrayTable.time: [test_time],
464-
DateTimeArrayTable.timestamp: [test_timestamp],
465-
DateTimeArrayTable.timestamptz: [test_timestamptz],
466-
DateTimeArrayTable.date_nullable: None,
467-
DateTimeArrayTable.time_nullable: None,
468-
DateTimeArrayTable.timestamp_nullable: None,
469-
DateTimeArrayTable.timestamptz_nullable: None,
467+
DateTimeDecimalArrayTable.date: [test_date],
468+
DateTimeDecimalArrayTable.time: [test_time],
469+
DateTimeDecimalArrayTable.timestamp: [test_timestamp],
470+
DateTimeDecimalArrayTable.timestamptz: [test_timestamptz],
471+
DateTimeDecimalArrayTable.decimal: [test_decimal],
472+
DateTimeDecimalArrayTable.date_nullable: None,
473+
DateTimeDecimalArrayTable.time_nullable: None,
474+
DateTimeDecimalArrayTable.timestamp_nullable: None,
475+
DateTimeDecimalArrayTable.timestamptz_nullable: None,
476+
DateTimeDecimalArrayTable.decimal_nullable: None,
470477
}
471478
).save().run_sync()
472479

473-
row = DateTimeArrayTable.objects().first().run_sync()
480+
row = DateTimeDecimalArrayTable.objects().first().run_sync()
474481
assert row is not None
475482

476483
self.assertListEqual(row.date, [test_date])
477484
self.assertListEqual(row.time, [test_time])
478485
self.assertListEqual(row.timestamp, [test_timestamp])
479486
self.assertListEqual(row.timestamptz, [test_timestamptz])
487+
self.assertListEqual(row.decimal, [test_decimal])
480488

481489
self.assertIsNone(row.date_nullable)
482490
self.assertIsNone(row.time_nullable)
483491
self.assertIsNone(row.timestamp_nullable)
484492
self.assertIsNone(row.timestamptz_nullable)
493+
self.assertIsNone(row.decimal_nullable)
485494

486495

487496
###############################################################################

0 commit comments

Comments
 (0)