Update dependency piccolo to ~=1.33.0 #92

Open
Renovate wants to merge 1 commit from renovate/piccolo-1.x into main
Collaborator

This PR contains the following updates:

Package Change Age Confidence
piccolo ~=1.32.0~=1.33.0 age confidence

Release Notes

piccolo-orm/piccolo (piccolo)

v1.33.0

Compare Source

UUID v7


Added support for UUID v7.

.. code-block:: python

  from piccolo.columns.defaults.uuid import UUID7

  class MyTable(Table):
      my_column = UUID(default=UUID7())

This provides superior insert performance and easier indexing compared to
UUID v4.

Requires Python 3.14, and Postgres 18 (otherwise extensions are needed).

``Coalesce``

Added the Coalesce function - which lets you specify a fall back if a null
value is found.

For example:

.. code-block:: python

await Album.select(
... Coalesce(Album.release_date, datetime.date(2050, 1, 1))
... )

Or you can use this abbreviated syntax:

.. code-block:: python

>>> await Album.select(
...     Album.release_date | datetime.date(2050, 1, 1)
... )

Other changes


* Fixed a bug with the Piccolo CLI, where custom names for commands weren't
  being applied (thanks to @​sinisaos for this and @​pelid for reporting the
  issue).
* Fixed typo in the ``get_related`` docstring (thanks to @​nightcityblade for
  this).
* Fixed bugs with queries when a column has ``db_column_name`` defined (thanks
  to @​VladislavYar for raising these issues).
* Improved the docs for ``Timestamp`` and ``Timestamptz`` columns.

-------------------------------------------------------------------------------

1.32.0
------

Added the ``having`` clause, which is useful when working with ``group_by``.

For example, here we get the number of albums per band, but exclude any bands
with less than 2 albums:

.. code-block:: python

    >>> from piccolo.query.functions.aggregate import Count

    >>> await Album.select(
    ...     Album.band.name.as_alias('band_name'),
    ...     Count()
    ... ).group_by(
    ...     Album.band
    ... ).having(
    ...     Count() >= 2
    ... )

    [
        {"band_name": "Pythonistas", "count": 2},
    ]

We also updated our CockroachDB support to the latest version (thanks to
@​sinisaos for this).

-------------------------------------------------------------------------------

1.31.0
------

* Added official Postgres 18 support.
* Removed graphlib backport (no longer needed in supported Python versions).
* Improved documentation for column kwargs.
* Updated README to mention other parts of the Piccolo ecosystem (thanks to
  @​sinisaos for this).
* Table instances can now be compared using the ``==`` operator, and will
  return ``True`` if they have the same primary key value (thanks to @​aarcex3
  and @​Skelmis for this).
* Fixed missing import for auto migrations when tables use
  ``LazyTableReference`` (thanks to @​sinisaos for this).
* Improved docs for the auto generated primary key (thanks to @​badlydrawnrob
  for this).
* Improved ``Table._table_str`` (this is most obvious in the playground, where
  the table definitions printed out now show more information - thanks to
  @​badlydrawnrob for raising this issue).
* Fixed a bug with ``ModelBuilder`` when using ``Array`` columns with
  ``choices`` defined.
* ``add_m2m`` now returns the id of the joining table row, to match the docs
  (thanks to @​diklios5768 for reporting this).
* Improved the docs for ``UUID`` columns (what the ``UUID4`` default value
  does).
* Moved connection pooling to its own page in the docs.
* Improved the ``on_conflict`` clause - a ``target`` must be specified if
  using ``DO UPDATE`` (thanks to @​mafuyuuu1 for raising this issue, and
  @​sinisaos for this fix).
* Changed Esmerald to Ravyn in the ASGI templates (thanks to @​sinisaos for
  this).
* Fixed a bug with auto migrations when changing a column to a foreign key - an
  exception was being raised (thanks to @​gsavchuk for raising this issue and
  @​sinisaos for this fix).
* ``Array(Numeric())`` columns now work with SQLite (thanks to @​sinisaos for
  this).
* UUID columns now use the built-in ``gen_random_uuid()`` function in Postgres
  to generate a default value, instead of using the ``uuid-ossp`` extension
  (thanks to @​sinisaos for this). See
  :ref:`this tutorial <UUIDColumnsMigrationTutorial>` for more details.

-------------------------------------------------------------------------------

1.30.0
------

Added support for Python 3.14 (thanks to @&#8203;sinisaos for this).

-------------------------------------------------------------------------------

1.29.0
------

* Fixed a bug with adding / subtracting  ``Integer`` columns from one another
  in queries (thanks to @&#8203;ryanvarley for this).
* Updated the ASGI templates, and BlackSheep dependencies (thanks to @&#8203;sinisaos
  for this).
* Fixed a bug where decimal values generated by ``ModelBuilder`` could be too
  large.
* Added an example ``M2M`` relationship in the playground to make learning
  ``M2M`` easier (thanks to @&#8203;sinisaos for this).
* Added documentation for ``MigrationManager.get_table_from_snapshot``, which
  is a way of getting a ``Table`` from the migration history - useful when
  running data migrations (thanks to @&#8203;sinisaos for this).
* Columns with the ``secret=True`` argument are now added to
  ``Table._meta.secret_columns`` (thanks to @&#8203;sinisaos for this).
* Added documentation for the ``migration`` table.
* Tidied up Pydantic tests (thanks to @&#8203;sinisaos for this).

-------------------------------------------------------------------------------

1.28.0
------

Playground improvements
  • Added an Array column to the playground (Album.awards), for easier
    experimentation with array columns.

  • CoachroachDB is now supported in the playground (thanks to @​sinisaos for this).

    .. code-block:: bash

    piccolo playground run --engine=cockroach

Functions


Added lots of useful array functions (thanks to @&#8203;sinisaos for this).

Here's an example, where we can easily fix a typo in an array using ``replace``:

.. code-block:: python

  >>> await Album.update({
  ...     Album.awards: Album.awards.replace('Grammy Award 2021', 'Grammy Award 2022')
  ... }, force=True)

The documentation for functions has also been improved (e.g. how to create a
custom function).

The ``Cast`` function is now more flexible.

``Array`` concantenation

Values can be prepended:

.. code-block:: python

await Album.update({
... Album.awards: ['Grammy Award 2020'] + Album.awards
... }, force=True)

And multiple arrays can be concatenated in one go:

.. code-block:: python

await Album.update({
... Album.awards: ['Grammy Award 2020'] + Album.awards + ['Grammy Award 2025']
... }, force=True)

is_in and not_in sub queries


You can now use sub queries within ``is_in`` and ``not_in``  Thanks to
@&#8203;sinisaos for this.

.. code-block:: python

  >>> await Band.select().where(
  ...     Band.id.is_in(
  ...         Concert.select(Concert.band_1).where(
  ...             Concert.starts >= datetime.datetime(year=2025, month=1, day=1)
  ...         )
  ...     )
  ... )

Other improvements
~~~~~~~~~~~~~~~~~~

* Auto convert a default value of ``0`` to ``0.0`` in ``Float`` columns.
* Modernised the type hints throughout the codebase (e.g. using ``list``
  instead of ``typing.List``). Thanks to @&#8203;sinisaos for this.
* Fixed a bug with auto migrations, where the ``Array`` base column class
  wasn't being imported.
* Improved M2M query performance by using sub selects (thanks to @&#8203;sinisaos for
  this).

-------------------------------------------------------------------------------

1.27.1
------

Improved the type annotations in ``ColumnKwargs`` - made some optional. Thanks
to @&#8203;stronk7 and @&#8203;sinisaos for their help with this.

-------------------------------------------------------------------------------

1.27.0
------

Improved auto completion / typo detection for column arguments.

For example:

.. code-block:: python

  class Band(Table):
      name = Varchar(nul=True)  # linters will now warn that nul is a typo (should be null)

Thanks to @&#8203;sinisaos for this.

-------------------------------------------------------------------------------

1.26.1
------

Updated the BlackSheep ASGI template - thanks to @&#8203;sinisaos for this.

Fixed a bug with auto migrations when a ``ForeignKey`` specifies
``target_column`` - multiple primary key columns were added to the migration
file. Thanks to @&#8203;waldner for reporting this issue.

Added a tutorial for moving tables between Piccolo apps - thanks to
@&#8203;sarvesh4396 for this.

-------------------------------------------------------------------------------

1.26.0
------

Improved auto migrations - ``ON DELETE`` and ``ON UPDATE`` can be modified
on ``ForeignKey`` columns. Thanks to @&#8203;sinisaos for this.

-------------------------------------------------------------------------------

1.25.0
------

Improvements to Piccolo app creation. When running the following:

.. code-block:: bash

  piccolo app new my_app

It now validates that the app name (``my_app`` in this case) is valid as a
Python package.

Also, there is now a ``--register`` flag, which automatically adds the new app
to the ``APP_REGISTRY`` in ``piccolo_conf.py``.

.. code-block:: python

  piccolo app new my_app --register

Other changes:

* ``table_finder`` can now use relative modules.
* Updated the Esmerald ASGI template (thanks to @&#8203;sinisaos for this).
* When using the ``remove`` method to delete a row from the database
  (``await some_band.remove()``), ``some_band._exists_in_db`` is now set to
  ``False``. Thanks to @&#8203;sinisaos for this fix.

-------------------------------------------------------------------------------

1.24.2
------

Fixed a bug with ``delete`` queries which had joins in the ``where`` clause.
For example:

.. code-block:: python

  >>> await Band.delete().where(Band.manager.name == 'Guido')

Thanks to @&#8203;HakierGrzonzo for reporting the issue, and @&#8203;sinisaos for the fix.

-------------------------------------------------------------------------------

1.24.1
------

Fixed a bug with default values in ``Timestamp`` and ``Timestamptz`` columns.
Thanks to @&#8203;splch for this.

-------------------------------------------------------------------------------

1.24.0
------

* Fixed a bug with ``get_or_create`` when a table has a column with both
  ``null=False`` and ``default=None`` - thanks to @&#8203;bymoye for reporting this
  issue.
* If a ``PostgresEngine`` uses the ``dsn`` argument for ``asyncpg``, this is
  now used by ``piccolo sql_shell run``. Thanks to @&#8203;abhishek-compro for
  suggesting this.
* Fixed the type annotation for the ``length`` argument of ``Varchar`` - it
  is allowed to be ``None``. Thanks to @&#8203;Compro-Prasad for this.

-------------------------------------------------------------------------------

1.23.0
------

* Added Quart, Sanic, and Falcon as supported ASGI frameworks (thanks to
  @&#8203;sinisaos for this).
* Fixed a bug with very large integers in SQLite.
* Fixed type annotation for ``Timestamptz`` default values (thanks to @&#8203;Skelmis
  for this).

-------------------------------------------------------------------------------

1.22.0
------

Python 3.13 is now officially supported.

``JSON`` / ``JSONB`` querying has been significantly improved. For example, if
we have this table:

.. code-block:: python

  class RecordingStudio(Table):
      facilities = JSONB()

And the ``facilities`` column contains the following JSON data:

.. code-block:: python

    {
        "technicians": [
            {"name": "Alice Jones"},
            {"name": "Bob Williams"},
        ]
    }

We can get the first technician name as follows:

.. code-block:: python

    >>> await RecordingStudio.select(
    ...     RecordingStudio.facilities["technicians"][0]["name"].as_alias("name")
    ... ).output(load_json=True)
    [{'name': 'Alice Jones'}, ...]

``TableStorage`` (used for dynamically creating Piccolo ``Table`` classes from
an existing database) was improved, to support a Dockerised version of Piccolo
Admin, which is coming soon.

-------------------------------------------------------------------------------

1.21.0
------

Postgres 17 is now officially supported.

Fixed a bug with joins, when a ``ForeignKey`` column had ``db_column_name``
specified. Thanks to @&#8203;jessemcl-flwls for reporting this issue.

-------------------------------------------------------------------------------

1.20.0
------

``get_related`` now works multiple layers deep:

.. code-block:: python

    concert = await Concert.objects().first()
    manager = await concert.get_related(Concert.band_1._.manager)

-------------------------------------------------------------------------------

1.19.1
------

Fixed a bug with the ``get_m2m`` method, which would raise a ``ValueError``
when no objects were found. It now handles this gracefully and returns an empty
list instead. Thanks to @&#8203;nVitius for this fix.

Improved the ASGI templates (including a fix for the latest Litestar version).
Thanks to @&#8203;sinisaos for this.

-------------------------------------------------------------------------------

1.19.0
------

Added support for row locking (i.e. ``SELECT ... FOR UPDATE``).

For example, if we have this table:

.. code-block:: python

  class Concert(Table):
      name = Varchar()
      tickets_available = Integer()

And we want to make sure that ``tickets_available`` never goes below 0, we can
do the following:

.. code-block:: python

  async def book_tickets(ticket_count: int):
      async with Concert._meta.db.transaction():
          concert = await Concert.objects().where(
              Concert.name == "Awesome Concert"
          ).first().lock_rows()

          if concert.tickets_available >= ticket_count:
              await concert.update_self({
                  Concert.tickets_available: Concert.tickets_available - ticket_count
              })
          else:
              raise ValueError("Not enough tickets are available!")

This means that when multiple transactions are running at the same time, it
isn't possible to book more tickets than are available.

Thanks to @&#8203;dkopitsa for adding this feature.

-------------------------------------------------------------------------------

1.18.0
------

``update_self``
~~~~~~~~~~~~~~~

Added the ``update_self`` method, which is an alternative to the ``save``
method. Here's an example where it's useful:

.. code-block:: python

### If we have a band object:
  >>> band = await Band.objects().get(name="Pythonistas")
  >>> band.popularity
  1000

### We can increment the popularity, based on the current value in the
### database:
  >>> await band.update_self({
  ...     Band.popularity: Band.popularity + 1
  ... })

### The new value is set on the object:
  >>> band.popularity
  1001

### It's safer than using the `save` method, because the popularity value on
### the object might be out of date with what's in the database:
  band.popularity += 1
  await band.save()

Thanks to @&#8203;trondhindenes for suggesting this feature.

Batch raw queries
~~~~~~~~~~~~~~~~~

The ``batch`` method can now be used with ``raw`` queries. For example:

.. code-block:: python

  async with await MyTable.raw("SELECT * FROM my_table").batch() as batch:
      async for _batch in batch:
          print(_batch)

This is useful when you expect a raw query to return a lot of data.

Thanks to @&#8203;devsarvesh92 for suggesting this feature.

-------------------------------------------------------------------------------

1.17.1
------

Fixed a bug with migrations, where altering a column type from ``Integer`` to
``Float`` could fail. Thanks to @&#8203;kurtportelli for reporting this issue.

-------------------------------------------------------------------------------

1.17.0
------

Each migration is automatically wrapped in a transaction - this can now be
disabled using the ``wrap_in_transaction`` argument:

.. code-block:: python

  manager = MigrationManager(
      wrap_in_transaction=False,
      ...
  )

This is useful when writing a manual migration, and you want to manage all of
the transaction logic yourself (or want multiple transactions).

``granian`` is now a supported server in the ASGI templates. Thanks to
@&#8203;sinisaos for this.

-------------------------------------------------------------------------------

1.16.0
------

Added custom async ``TestCase`` subclasses, to help with testing.

For example ``AsyncTransactionTest``, which wraps each test in a transaction
automatically:

.. code-block:: python

  class TestBandEndpoint(AsyncTransactionTest):

      async def test_band_response(self):
          """
          Make sure the endpoint returns a 200.
          """

### This data automatically gets removed from the database when the
### test finishes:
          band = Band({Band.name: "Pythonistas"})
          await band.save()

### Using an API testing client, like httpx:
          response = await client.get(f"/bands/{band.id}/")
          self.assertEqual(response.status_code, 200)

And ``AsyncTableTest``, which automatically creates and drops tables:

.. code-block:: python

  class TestBand(AsyncTableTest):

### These tables automatically get created and dropped:
      tables = [Band]

      async def test_band(self):
          ...

-------------------------------------------------------------------------------

1.15.0
------

Improved ``refresh`` - it now works with prefetched objects. For example:

.. code-block:: python

  >>> band = await Band.objects(Band.manager).first()
  >>> band.manager.name
  "Guido"

### If the manager has changed in the database, when we refresh the band, the
### manager object will also be updated:
  >>> await band.refresh()
  >>> band.manager.name
  "New name"

Also, improved the error messages when creating a ``BaseUser`` - thanks to
@&#8203;haaavk for this.

-------------------------------------------------------------------------------

1.14.0
------

Laying the foundations for alterative Postgres database drivers (e.g.
``psqlpy``). Thanks to @&#8203;insani7y and @&#8203;chandr-andr for their help with this.

.. warning::
  The SQL generated by Piccolo changed slightly in this release. Aliases used
  to be like ``"manager$name"`` but now they are like ``"manager.name"``
  (note ``$`` changed to ``.``). If you are using ``SelectRaw`` in your queries
  to refer to these columns, then they will need updating. Please let us know
  if you encounter any other issues.

-------------------------------------------------------------------------------

1.13.1
------

In Piccolo ``1.6.0`` we moved some aggregate functions to a new file. We now
re-export them from their original location to keep backwards compatibility.
Thanks to @&#8203;sarvesh-deserve for reporting this issue.

-------------------------------------------------------------------------------

1.13.0
------

Improved ``LazyTableReference``, to help prevent circular import errors.

-------------------------------------------------------------------------------

1.12.0
------

* Added documentation for one to one fields.
* Upgraded ASGI templates (thanks to @&#8203;sinisaos for this).
* Migrations can now be hardcoded as fake.
* Refactored tests to reduce boilerplate code.
* Updated documentation dependencies.

-------------------------------------------------------------------------------

1.11.0
------

Added datetime functions, for example ``Year``:

.. code-block:: python

    >>> from piccolo.query.functions import Year
    >>> await Concert.select(Year(Concert.starts, alias="starts_year"))
    [{'starts_year': 2024}]

Added the ``Concat`` function, for concatenating strings:

.. code-block:: python

    >>> from piccolo.query.functions import Concat
    >>> await Band.select(
    ...     Concat(
    ...         Band.name,
    ...         '-',
    ...         Band.manager._.name,
    ...         alias="name_and_manager"
    ...     )
    ... )
    [{"name_and_manager": "Pythonistas-Guido"}]

-------------------------------------------------------------------------------

1.10.0
------

Added ``not_any`` method for ``Array`` columns. This will return rows where an
array doesn't contain the given value. For example:

.. code-block:: python

  class MyTable(Table):
      array_column = Array(Integer())

  >>> await MyTable.select(
  ...     MyTable.array_column
  ... ).where(
  ...     MyTable.array_column.not_any(1)
  ... )
  [{"array_column": [4, 5, 6]}]

Also fixed a bunch of Pylance linter warnings across the codebase.

-------------------------------------------------------------------------------

1.9.0
-----

Added some math functions, for example ``Abs``, ``Ceil``, ``Floor`` and
``Round``.

.. code-block:: python

  >>> from piccolo.query.functions import Round
  >>> await Ticket.select(Round(Ticket.price, alias="price"))
  [{'price': 50.0}]

Added more operators to ``QueryString`` (multiply, divide, modulus, power), so
we can do things like:

.. code-block:: python

  >>> await Ticket.select(Round(Ticket.price) * 2)
  [{'price': 100.0}]

Fixed some edge cases around defaults for ``Array`` columns.

.. code-block:: python

  def get_default():

### This used to fail:
      return [datetime.time(hour=8, minute=0)]

  class MyTable(Table):
      times = Array(Time(), default=get_default)

Fixed some deprecation warnings, and improved CockroachDB array tests.

-------------------------------------------------------------------------------

1.8.0
-----

Added the ``Cast`` function, for performing type conversion.

Here's an example, where we convert a ``timestamp`` to ``time``:

.. code-block:: python

    >>> from piccolo.columns import Time
    >>> from piccolo.query.functions import Cast

    >>> await Concert.select(Cast(Concert.starts, Time()))
    [{'starts': datetime.time(19, 0)}]

A new section was also added to the docs describing functions in more detail.

-------------------------------------------------------------------------------

1.7.0
-----

Arrays of ``Date`` / ``Time`` / ``Timestamp`` / ``Timestamptz`` now work in
SQLite.

For example:

.. code-block:: python

  class MyTable(Table):
      times = Array(Time())
      dates = Array(Date())
      timestamps = Array(Timestamp())
      timestamps_tz = Array(Timestamptz())

-------------------------------------------------------------------------------

1.6.0
-----

Added support for a bunch of Postgres functions, like ``Upper``, ``Lower``,
``Length``, and ``Ltrim``. They can be used in ``select`` queries:

.. code-block:: python

  from piccolo.query.functions.string import Upper
  >>> await Band.select(Upper(Band.name, alias="name"))
  [{"name": "PYTHONISTAS"}]

And also in ``where`` clauses:

.. code-block:: python

  >>> await Band.select().where(Upper(Band.manager.name) == 'GUIDO')
  [{"name": "Pythonistas"}]

-------------------------------------------------------------------------------

1.5.2
-----

Added an ``Album`` table to the playground, along with some other
improvements.

Fixed a bug with the ``output(load_json=True)`` clause, when used on joined
tables.

-------------------------------------------------------------------------------

1.5.1
-----

Fixed a bug with the CLI when reversing migrations (thanks to @&#8203;metakot for
reporting this).

Updated the ASGI templates (thanks to @&#8203;tarsil for adding Lilya).

-------------------------------------------------------------------------------

1.5.0
-----

Lots of internal improvements, mostly to support new functionality in Piccolo
Admin.

-------------------------------------------------------------------------------

1.4.2
-----

Improved how ``ModelBuilder`` handles recursive foreign keys.

-------------------------------------------------------------------------------

1.4.1
-----

Fixed an edge case with auto migrations.

If starting from a table like this, with a custom primary key column:

.. code-block:: python

  class MyTable(Table):
      id = UUID(primary_key=True)

When a foreign key is added to the table which references itself:

.. code-block:: python

  class MyTable(Table):
      id = UUID(primary_key=True)
      fk = ForeignKey("self")

The auto migrations could fail in some situations.

-------------------------------------------------------------------------------

1.4.0
-----

Improved how ``create_pydantic_model`` handles ``Array`` columns:

* Multidimensional arrays (e.g. ``Array(Array(Integer))``) have more accurate
  types.
* ``Array(Email())`` now validates that each item in the list is an email
  address.
* ``Array(Varchar(length=10))`` now validates that each item is the correct
  length (i.e. 10 in this example).

Other changes
~~~~~~~~~~~~~

Some Pylance errors were fixed in the codebase.

-------------------------------------------------------------------------------

1.3.2
-----

Fixed a bug with nested array columns containing ``BigInt``. For example:

.. code-block:: python

  class MyTable(Table):
      my_column = Array(Array(BigInt))

Thanks to @&#8203;AmazingAkai for reporting this issue.

-------------------------------------------------------------------------------

1.3.1
-----

Fixed a bug with foreign keys which reference ``BigSerial`` primary keys.
Thanks to @&#8203;Abdelhadi92 for reporting this issue.

-------------------------------------------------------------------------------

1.3.0
-----

Added the ``piccolo user list`` command - a quick and convenient way of listing
Piccolo Admin users from the command line.

``ModelBuilder`` now creates timezone aware ``datetime`` objects for
``Timestamptz`` columns.

Updated the ASGI templates.

SQLite auto migrations are now allowed. We used to raise an exception, but
now we output a warning instead. While SQLite auto migrations aren't as feature
rich as Postgres, they work fine for simple use cases.

-------------------------------------------------------------------------------

1.2.0
-----

There's now an alternative syntax for joins, which works really well with
static type checkers like Mypy and Pylance.

The traditional syntax (which continues to work as before):

.. code-block:: python

### Get the band name, and the manager's name from a related table
  await Band.select(Band.name, Band.manager.name)

The alternative syntax is as follows:

.. code-block:: python

  await Band.select(Band.name, Band.manager._.name)

Note how we use ``._.`` instead of ``.`` after a ``ForeignKey``.

This offers a considerably better static typing experience. In the above
example, type checkers know that ``Band.manager._.name`` refers to the ``name``
column on the ``Manager`` table. This means typos can be detected, and code
navigation is easier.

Other changes
~~~~~~~~~~~~~

* Improve static typing for ``get_related``.
* Added support for the ``esmerald`` ASGI framework.

-------------------------------------------------------------------------------

1.1.1
-----

Piccolo allows the user to specify savepoint names which are used in
transactions. For example:

.. code-block:: python

    async with DB.transaction() as transaction:
        await Band.insert(Band(name='Pythonistas'))

### Passing in a savepoint name is optional:
        savepoint_1 = await transaction.savepoint('savepoint_1')

        await Band.insert(Band(name='Terrible band'))

### Oops, I made a mistake!
        await savepoint_1.rollback_to()

Postgres doesn't allow us to parameterise savepoint names, which means there's
a small chance of SQL injection, if for some reason the savepoint names were
generated from end-user input. Even though the likelihood is very low, it's
best to be safe. We now validate the savepoint name, to make sure it can only
contain certain safe characters. Thanks to @&#8203;Skelmis for making this change.

-------------------------------------------------------------------------------

1.1.0
-----

Added support for Python 3.12.

Modified ``create_pydantic_model``, so additional information is returned in
the JSON schema to distinguish between ``Timestamp`` and ``Timestamptz``
columns. This will be used for future Piccolo Admin enhancements.

-------------------------------------------------------------------------------

1.0.0
-----

Piccolo v1 is now available!

We migrated to Pydantic v2, and also migrated Piccolo Admin to Vue 3, which
puts the project in a good place moving forward.

We don't anticipate any major issues for people who are upgrading. If you
encounter any bugs let us know.

Make sure you have v1 of Piccolo, Piccolo API, and Piccolo Admin.

-------------------------------------------------------------------------------

1.0a3
-----

Namespaced all custom values we added to Pydantic's JSON schema for easier
maintenance.

-------------------------------------------------------------------------------

1.0a2
-----

All of the changes from 0.120.0 merged into the v1 branch.

-------------------------------------------------------------------------------

0.121.0
-------

Modified the ``BaseUser.login`` logic so all code paths take the same time.
Thanks to @&#8203;Skelmis for this.

-------------------------------------------------------------------------------

0.120.0
-------

Improved how ``ModelBuilder`` generates JSON data.

The number of password hash iterations used in ``BaseUser`` has been increased
to keep pace with the latest guidance from OWASP - thanks to @&#8203;Skelmis for this.

Fixed a bug with auto migrations when the table is in a schema.

-------------------------------------------------------------------------------

1.0a1
-----

Initial alpha release of Piccolo v1, with Pydantic v2 support.

-------------------------------------------------------------------------------

0.119.0
-------

``ModelBuilder`` now works with ``LazyTableReference`` (which is used when we
have circular references caused by a ``ForeignKey``).

With this table:

.. code-block:: python

  class Band(Table):
      manager = ForeignKey(
          LazyTableReference(
              'Manager',
              module_path='some.other.folder.tables'
          )
      )

We can now create a dynamic test fixture:

.. code-block:: python

    my_model = await ModelBuilder.build(Band)

-------------------------------------------------------------------------------

0.118.0
-------

If you have lots of Piccolo apps, you can now create auto migrations for them
all in one go:

.. code-block:: bash

  piccolo migrations new all --auto

Thanks to @&#8203;hoosnick for suggesting this new feature.

The documentation for running migrations has also been improved, as well as
improvements to the sorting of migrations based on their dependencies.

Support for Python 3.7 was dropped in this release as it's now end of life.

-------------------------------------------------------------------------------

0.117.0
-------

Version pinning Pydantic to v1, as v2 has breaking changes.

We will add support for Pydantic v2 in a future release.

Thanks to @&#8203;sinisaos for helping with this.

-------------------------------------------------------------------------------

0.116.0
-------

Fixture formatting
~~~~~~~~~~~~~~~~~~

When creating a fixture:

.. code-block:: bash

  piccolo fixtures dump

The JSON output is now nicely formatted, which is useful because we can pipe
it straight to a file, and commit it to Git without having to manually run a
formatter on it.

.. code-block:: bash

  piccolo fixtures dump > my_fixture.json

Thanks to @&#8203;sinisaos for this.

Protected table names
~~~~~~~~~~~~~~~~~~~~~

We used to raise a ``ValueError`` if a table was called ``user``.

.. code-block:: python

  class User(Table):  # ValueError!
      ...

It's because ``user`` is already used by Postgres (e.g. try ``SELECT user`` or
``SELECT * FROM user``).

We now emit a warning instead for these reasons:

* Piccolo wraps table names in quotes to avoid clashes with reserved keywords.
* Sometimes you're stuck with a table name from a pre-existing schema, and
  can't easily rename it.

Re-export ``WhereRaw``
~~~~~~~~~~~~~~~~~~~~~~

If you want to write raw SQL in your where queries you use ``WhereRaw``:

.. code-block:: python

  >>> Band.select().where(WhereRaw('TRIM(name) = {}', 'Pythonistas'))

You can now import it from ``piccolo.query`` to be consistent with
``SelectRaw`` and ``OrderByRaw``.

.. code-block:: python

  from piccolo.query import WhereRaw

-------------------------------------------------------------------------------

0.115.0
-------

Fixture upserting
~~~~~~~~~~~~~~~~~

Fixtures can now be upserted. For example:

.. code-block:: bash

  piccolo fixtures load my_fixture.json --on_conflict='DO UPDATE'

The options are:

* ``DO NOTHING``, meaning any rows with a matching primary key will be left
  alone.
* ``DO UPDATE``, meaning any rows with a matching primary key will be updated.

This is really useful, as you can now edit fixtures and load them multiple
times without getting foreign key constraint errors.

Schema fixes
~~~~~~~~~~~~

We recently added support for schemas, for example:

.. code-block:: python

  class Band(Table, schema='music'):
      ...

This release contains:

* A fix for migrations when changing a table's schema back to 'public' (thanks to
  @&#8203;sinisaos for discovering this).
* A fix for ``M2M`` queries, when the tables are in a schema other than
  'public' (thanks to @&#8203;quinnalfaro for reporting this).

Added ``distinct`` method to ``count`` queries

We recently added support for COUNT DISTINCT queries. The syntax is:

.. code-block:: python

await Concert.count(distinct=[Concert.start_date])

The following alternative syntax now also works (just to be consistent with
other queries like select):

.. code-block:: python

await Concert.count().distinct([Concert.start_date])



Configuration

📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR has been generated by Renovate Bot.

This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---| | [piccolo](https://github.com/piccolo-orm/piccolo) | `~=1.32.0` → `~=1.33.0` | ![age](https://developer.mend.io/api/mc/badges/age/pypi/piccolo/1.33.0?slim=true) | ![confidence](https://developer.mend.io/api/mc/badges/confidence/pypi/piccolo/1.32.0/1.33.0?slim=true) | --- ### Release Notes <details> <summary>piccolo-orm/piccolo (piccolo)</summary> ### [`v1.33.0`](https://github.com/piccolo-orm/piccolo/blob/HEAD/CHANGES.rst#1330) [Compare Source](https://github.com/piccolo-orm/piccolo/compare/1.32.0...1.33.0) UUID v7 ``` Added support for UUID v7. .. code-block:: python from piccolo.columns.defaults.uuid import UUID7 class MyTable(Table): my_column = UUID(default=UUID7()) This provides superior insert performance and easier indexing compared to UUID v4. Requires Python 3.14, and Postgres 18 (otherwise extensions are needed). ``Coalesce`` ``` Added the `Coalesce` function - which lets you specify a fall back if a null value is found. For example: .. code-block:: python > > > await Album.select( > > > ... Coalesce(Album.release\_date, datetime.date(2050, 1, 1)) > > > ... ) Or you can use this abbreviated syntax: .. code-block:: python ``` >>> await Album.select( ... Album.release_date | datetime.date(2050, 1, 1) ... ) ``` Other changes ``` * Fixed a bug with the Piccolo CLI, where custom names for commands weren't being applied (thanks to @&#8203;sinisaos for this and @&#8203;pelid for reporting the issue). * Fixed typo in the ``get_related`` docstring (thanks to @&#8203;nightcityblade for this). * Fixed bugs with queries when a column has ``db_column_name`` defined (thanks to @&#8203;VladislavYar for raising these issues). * Improved the docs for ``Timestamp`` and ``Timestamptz`` columns. ------------------------------------------------------------------------------- 1.32.0 ------ Added the ``having`` clause, which is useful when working with ``group_by``. For example, here we get the number of albums per band, but exclude any bands with less than 2 albums: .. code-block:: python >>> from piccolo.query.functions.aggregate import Count >>> await Album.select( ... Album.band.name.as_alias('band_name'), ... Count() ... ).group_by( ... Album.band ... ).having( ... Count() >= 2 ... ) [ {"band_name": "Pythonistas", "count": 2}, ] We also updated our CockroachDB support to the latest version (thanks to @&#8203;sinisaos for this). ------------------------------------------------------------------------------- 1.31.0 ------ * Added official Postgres 18 support. * Removed graphlib backport (no longer needed in supported Python versions). * Improved documentation for column kwargs. * Updated README to mention other parts of the Piccolo ecosystem (thanks to @&#8203;sinisaos for this). * Table instances can now be compared using the ``==`` operator, and will return ``True`` if they have the same primary key value (thanks to @&#8203;aarcex3 and @&#8203;Skelmis for this). * Fixed missing import for auto migrations when tables use ``LazyTableReference`` (thanks to @&#8203;sinisaos for this). * Improved docs for the auto generated primary key (thanks to @&#8203;badlydrawnrob for this). * Improved ``Table._table_str`` (this is most obvious in the playground, where the table definitions printed out now show more information - thanks to @&#8203;badlydrawnrob for raising this issue). * Fixed a bug with ``ModelBuilder`` when using ``Array`` columns with ``choices`` defined. * ``add_m2m`` now returns the id of the joining table row, to match the docs (thanks to @&#8203;diklios5768 for reporting this). * Improved the docs for ``UUID`` columns (what the ``UUID4`` default value does). * Moved connection pooling to its own page in the docs. * Improved the ``on_conflict`` clause - a ``target`` must be specified if using ``DO UPDATE`` (thanks to @&#8203;mafuyuuu1 for raising this issue, and @&#8203;sinisaos for this fix). * Changed Esmerald to Ravyn in the ASGI templates (thanks to @&#8203;sinisaos for this). * Fixed a bug with auto migrations when changing a column to a foreign key - an exception was being raised (thanks to @&#8203;gsavchuk for raising this issue and @&#8203;sinisaos for this fix). * ``Array(Numeric())`` columns now work with SQLite (thanks to @&#8203;sinisaos for this). * UUID columns now use the built-in ``gen_random_uuid()`` function in Postgres to generate a default value, instead of using the ``uuid-ossp`` extension (thanks to @&#8203;sinisaos for this). See :ref:`this tutorial <UUIDColumnsMigrationTutorial>` for more details. ------------------------------------------------------------------------------- 1.30.0 ------ Added support for Python 3.14 (thanks to @&#8203;sinisaos for this). ------------------------------------------------------------------------------- 1.29.0 ------ * Fixed a bug with adding / subtracting ``Integer`` columns from one another in queries (thanks to @&#8203;ryanvarley for this). * Updated the ASGI templates, and BlackSheep dependencies (thanks to @&#8203;sinisaos for this). * Fixed a bug where decimal values generated by ``ModelBuilder`` could be too large. * Added an example ``M2M`` relationship in the playground to make learning ``M2M`` easier (thanks to @&#8203;sinisaos for this). * Added documentation for ``MigrationManager.get_table_from_snapshot``, which is a way of getting a ``Table`` from the migration history - useful when running data migrations (thanks to @&#8203;sinisaos for this). * Columns with the ``secret=True`` argument are now added to ``Table._meta.secret_columns`` (thanks to @&#8203;sinisaos for this). * Added documentation for the ``migration`` table. * Tidied up Pydantic tests (thanks to @&#8203;sinisaos for this). ------------------------------------------------------------------------------- 1.28.0 ------ Playground improvements ``` - Added an `Array` column to the playground (`Album.awards`), for easier experimentation with array columns. - CoachroachDB is now supported in the playground (thanks to [@&#8203;sinisaos](https://github.com/sinisaos) for this). .. code-block:: bash piccolo playground run --engine=cockroach Functions ``` Added lots of useful array functions (thanks to @&#8203;sinisaos for this). Here's an example, where we can easily fix a typo in an array using ``replace``: .. code-block:: python >>> await Album.update({ ... Album.awards: Album.awards.replace('Grammy Award 2021', 'Grammy Award 2022') ... }, force=True) The documentation for functions has also been improved (e.g. how to create a custom function). The ``Cast`` function is now more flexible. ``Array`` concantenation ``` Values can be prepended: .. code-block:: python > > > await Album.update({ > > > ... Album.awards: \['Grammy Award 2020'] + Album.awards > > > ... }, force=True) And multiple arrays can be concatenated in one go: .. code-block:: python > > > await Album.update({ > > > ... Album.awards: \['Grammy Award 2020'] + Album.awards + \['Grammy Award 2025'] > > > ... }, force=True) `is_in` and `not_in` sub queries ``` You can now use sub queries within ``is_in`` and ``not_in`` Thanks to @&#8203;sinisaos for this. .. code-block:: python >>> await Band.select().where( ... Band.id.is_in( ... Concert.select(Concert.band_1).where( ... Concert.starts >= datetime.datetime(year=2025, month=1, day=1) ... ) ... ) ... ) Other improvements ~~~~~~~~~~~~~~~~~~ * Auto convert a default value of ``0`` to ``0.0`` in ``Float`` columns. * Modernised the type hints throughout the codebase (e.g. using ``list`` instead of ``typing.List``). Thanks to @&#8203;sinisaos for this. * Fixed a bug with auto migrations, where the ``Array`` base column class wasn't being imported. * Improved M2M query performance by using sub selects (thanks to @&#8203;sinisaos for this). ------------------------------------------------------------------------------- 1.27.1 ------ Improved the type annotations in ``ColumnKwargs`` - made some optional. Thanks to @&#8203;stronk7 and @&#8203;sinisaos for their help with this. ------------------------------------------------------------------------------- 1.27.0 ------ Improved auto completion / typo detection for column arguments. For example: .. code-block:: python class Band(Table): name = Varchar(nul=True) # linters will now warn that nul is a typo (should be null) Thanks to @&#8203;sinisaos for this. ------------------------------------------------------------------------------- 1.26.1 ------ Updated the BlackSheep ASGI template - thanks to @&#8203;sinisaos for this. Fixed a bug with auto migrations when a ``ForeignKey`` specifies ``target_column`` - multiple primary key columns were added to the migration file. Thanks to @&#8203;waldner for reporting this issue. Added a tutorial for moving tables between Piccolo apps - thanks to @&#8203;sarvesh4396 for this. ------------------------------------------------------------------------------- 1.26.0 ------ Improved auto migrations - ``ON DELETE`` and ``ON UPDATE`` can be modified on ``ForeignKey`` columns. Thanks to @&#8203;sinisaos for this. ------------------------------------------------------------------------------- 1.25.0 ------ Improvements to Piccolo app creation. When running the following: .. code-block:: bash piccolo app new my_app It now validates that the app name (``my_app`` in this case) is valid as a Python package. Also, there is now a ``--register`` flag, which automatically adds the new app to the ``APP_REGISTRY`` in ``piccolo_conf.py``. .. code-block:: python piccolo app new my_app --register Other changes: * ``table_finder`` can now use relative modules. * Updated the Esmerald ASGI template (thanks to @&#8203;sinisaos for this). * When using the ``remove`` method to delete a row from the database (``await some_band.remove()``), ``some_band._exists_in_db`` is now set to ``False``. Thanks to @&#8203;sinisaos for this fix. ------------------------------------------------------------------------------- 1.24.2 ------ Fixed a bug with ``delete`` queries which had joins in the ``where`` clause. For example: .. code-block:: python >>> await Band.delete().where(Band.manager.name == 'Guido') Thanks to @&#8203;HakierGrzonzo for reporting the issue, and @&#8203;sinisaos for the fix. ------------------------------------------------------------------------------- 1.24.1 ------ Fixed a bug with default values in ``Timestamp`` and ``Timestamptz`` columns. Thanks to @&#8203;splch for this. ------------------------------------------------------------------------------- 1.24.0 ------ * Fixed a bug with ``get_or_create`` when a table has a column with both ``null=False`` and ``default=None`` - thanks to @&#8203;bymoye for reporting this issue. * If a ``PostgresEngine`` uses the ``dsn`` argument for ``asyncpg``, this is now used by ``piccolo sql_shell run``. Thanks to @&#8203;abhishek-compro for suggesting this. * Fixed the type annotation for the ``length`` argument of ``Varchar`` - it is allowed to be ``None``. Thanks to @&#8203;Compro-Prasad for this. ------------------------------------------------------------------------------- 1.23.0 ------ * Added Quart, Sanic, and Falcon as supported ASGI frameworks (thanks to @&#8203;sinisaos for this). * Fixed a bug with very large integers in SQLite. * Fixed type annotation for ``Timestamptz`` default values (thanks to @&#8203;Skelmis for this). ------------------------------------------------------------------------------- 1.22.0 ------ Python 3.13 is now officially supported. ``JSON`` / ``JSONB`` querying has been significantly improved. For example, if we have this table: .. code-block:: python class RecordingStudio(Table): facilities = JSONB() And the ``facilities`` column contains the following JSON data: .. code-block:: python { "technicians": [ {"name": "Alice Jones"}, {"name": "Bob Williams"}, ] } We can get the first technician name as follows: .. code-block:: python >>> await RecordingStudio.select( ... RecordingStudio.facilities["technicians"][0]["name"].as_alias("name") ... ).output(load_json=True) [{'name': 'Alice Jones'}, ...] ``TableStorage`` (used for dynamically creating Piccolo ``Table`` classes from an existing database) was improved, to support a Dockerised version of Piccolo Admin, which is coming soon. ------------------------------------------------------------------------------- 1.21.0 ------ Postgres 17 is now officially supported. Fixed a bug with joins, when a ``ForeignKey`` column had ``db_column_name`` specified. Thanks to @&#8203;jessemcl-flwls for reporting this issue. ------------------------------------------------------------------------------- 1.20.0 ------ ``get_related`` now works multiple layers deep: .. code-block:: python concert = await Concert.objects().first() manager = await concert.get_related(Concert.band_1._.manager) ------------------------------------------------------------------------------- 1.19.1 ------ Fixed a bug with the ``get_m2m`` method, which would raise a ``ValueError`` when no objects were found. It now handles this gracefully and returns an empty list instead. Thanks to @&#8203;nVitius for this fix. Improved the ASGI templates (including a fix for the latest Litestar version). Thanks to @&#8203;sinisaos for this. ------------------------------------------------------------------------------- 1.19.0 ------ Added support for row locking (i.e. ``SELECT ... FOR UPDATE``). For example, if we have this table: .. code-block:: python class Concert(Table): name = Varchar() tickets_available = Integer() And we want to make sure that ``tickets_available`` never goes below 0, we can do the following: .. code-block:: python async def book_tickets(ticket_count: int): async with Concert._meta.db.transaction(): concert = await Concert.objects().where( Concert.name == "Awesome Concert" ).first().lock_rows() if concert.tickets_available >= ticket_count: await concert.update_self({ Concert.tickets_available: Concert.tickets_available - ticket_count }) else: raise ValueError("Not enough tickets are available!") This means that when multiple transactions are running at the same time, it isn't possible to book more tickets than are available. Thanks to @&#8203;dkopitsa for adding this feature. ------------------------------------------------------------------------------- 1.18.0 ------ ``update_self`` ~~~~~~~~~~~~~~~ Added the ``update_self`` method, which is an alternative to the ``save`` method. Here's an example where it's useful: .. code-block:: python ### If we have a band object: >>> band = await Band.objects().get(name="Pythonistas") >>> band.popularity 1000 ### We can increment the popularity, based on the current value in the ### database: >>> await band.update_self({ ... Band.popularity: Band.popularity + 1 ... }) ### The new value is set on the object: >>> band.popularity 1001 ### It's safer than using the `save` method, because the popularity value on ### the object might be out of date with what's in the database: band.popularity += 1 await band.save() Thanks to @&#8203;trondhindenes for suggesting this feature. Batch raw queries ~~~~~~~~~~~~~~~~~ The ``batch`` method can now be used with ``raw`` queries. For example: .. code-block:: python async with await MyTable.raw("SELECT * FROM my_table").batch() as batch: async for _batch in batch: print(_batch) This is useful when you expect a raw query to return a lot of data. Thanks to @&#8203;devsarvesh92 for suggesting this feature. ------------------------------------------------------------------------------- 1.17.1 ------ Fixed a bug with migrations, where altering a column type from ``Integer`` to ``Float`` could fail. Thanks to @&#8203;kurtportelli for reporting this issue. ------------------------------------------------------------------------------- 1.17.0 ------ Each migration is automatically wrapped in a transaction - this can now be disabled using the ``wrap_in_transaction`` argument: .. code-block:: python manager = MigrationManager( wrap_in_transaction=False, ... ) This is useful when writing a manual migration, and you want to manage all of the transaction logic yourself (or want multiple transactions). ``granian`` is now a supported server in the ASGI templates. Thanks to @&#8203;sinisaos for this. ------------------------------------------------------------------------------- 1.16.0 ------ Added custom async ``TestCase`` subclasses, to help with testing. For example ``AsyncTransactionTest``, which wraps each test in a transaction automatically: .. code-block:: python class TestBandEndpoint(AsyncTransactionTest): async def test_band_response(self): """ Make sure the endpoint returns a 200. """ ### This data automatically gets removed from the database when the ### test finishes: band = Band({Band.name: "Pythonistas"}) await band.save() ### Using an API testing client, like httpx: response = await client.get(f"/bands/{band.id}/") self.assertEqual(response.status_code, 200) And ``AsyncTableTest``, which automatically creates and drops tables: .. code-block:: python class TestBand(AsyncTableTest): ### These tables automatically get created and dropped: tables = [Band] async def test_band(self): ... ------------------------------------------------------------------------------- 1.15.0 ------ Improved ``refresh`` - it now works with prefetched objects. For example: .. code-block:: python >>> band = await Band.objects(Band.manager).first() >>> band.manager.name "Guido" ### If the manager has changed in the database, when we refresh the band, the ### manager object will also be updated: >>> await band.refresh() >>> band.manager.name "New name" Also, improved the error messages when creating a ``BaseUser`` - thanks to @&#8203;haaavk for this. ------------------------------------------------------------------------------- 1.14.0 ------ Laying the foundations for alterative Postgres database drivers (e.g. ``psqlpy``). Thanks to @&#8203;insani7y and @&#8203;chandr-andr for their help with this. .. warning:: The SQL generated by Piccolo changed slightly in this release. Aliases used to be like ``"manager$name"`` but now they are like ``"manager.name"`` (note ``$`` changed to ``.``). If you are using ``SelectRaw`` in your queries to refer to these columns, then they will need updating. Please let us know if you encounter any other issues. ------------------------------------------------------------------------------- 1.13.1 ------ In Piccolo ``1.6.0`` we moved some aggregate functions to a new file. We now re-export them from their original location to keep backwards compatibility. Thanks to @&#8203;sarvesh-deserve for reporting this issue. ------------------------------------------------------------------------------- 1.13.0 ------ Improved ``LazyTableReference``, to help prevent circular import errors. ------------------------------------------------------------------------------- 1.12.0 ------ * Added documentation for one to one fields. * Upgraded ASGI templates (thanks to @&#8203;sinisaos for this). * Migrations can now be hardcoded as fake. * Refactored tests to reduce boilerplate code. * Updated documentation dependencies. ------------------------------------------------------------------------------- 1.11.0 ------ Added datetime functions, for example ``Year``: .. code-block:: python >>> from piccolo.query.functions import Year >>> await Concert.select(Year(Concert.starts, alias="starts_year")) [{'starts_year': 2024}] Added the ``Concat`` function, for concatenating strings: .. code-block:: python >>> from piccolo.query.functions import Concat >>> await Band.select( ... Concat( ... Band.name, ... '-', ... Band.manager._.name, ... alias="name_and_manager" ... ) ... ) [{"name_and_manager": "Pythonistas-Guido"}] ------------------------------------------------------------------------------- 1.10.0 ------ Added ``not_any`` method for ``Array`` columns. This will return rows where an array doesn't contain the given value. For example: .. code-block:: python class MyTable(Table): array_column = Array(Integer()) >>> await MyTable.select( ... MyTable.array_column ... ).where( ... MyTable.array_column.not_any(1) ... ) [{"array_column": [4, 5, 6]}] Also fixed a bunch of Pylance linter warnings across the codebase. ------------------------------------------------------------------------------- 1.9.0 ----- Added some math functions, for example ``Abs``, ``Ceil``, ``Floor`` and ``Round``. .. code-block:: python >>> from piccolo.query.functions import Round >>> await Ticket.select(Round(Ticket.price, alias="price")) [{'price': 50.0}] Added more operators to ``QueryString`` (multiply, divide, modulus, power), so we can do things like: .. code-block:: python >>> await Ticket.select(Round(Ticket.price) * 2) [{'price': 100.0}] Fixed some edge cases around defaults for ``Array`` columns. .. code-block:: python def get_default(): ### This used to fail: return [datetime.time(hour=8, minute=0)] class MyTable(Table): times = Array(Time(), default=get_default) Fixed some deprecation warnings, and improved CockroachDB array tests. ------------------------------------------------------------------------------- 1.8.0 ----- Added the ``Cast`` function, for performing type conversion. Here's an example, where we convert a ``timestamp`` to ``time``: .. code-block:: python >>> from piccolo.columns import Time >>> from piccolo.query.functions import Cast >>> await Concert.select(Cast(Concert.starts, Time())) [{'starts': datetime.time(19, 0)}] A new section was also added to the docs describing functions in more detail. ------------------------------------------------------------------------------- 1.7.0 ----- Arrays of ``Date`` / ``Time`` / ``Timestamp`` / ``Timestamptz`` now work in SQLite. For example: .. code-block:: python class MyTable(Table): times = Array(Time()) dates = Array(Date()) timestamps = Array(Timestamp()) timestamps_tz = Array(Timestamptz()) ------------------------------------------------------------------------------- 1.6.0 ----- Added support for a bunch of Postgres functions, like ``Upper``, ``Lower``, ``Length``, and ``Ltrim``. They can be used in ``select`` queries: .. code-block:: python from piccolo.query.functions.string import Upper >>> await Band.select(Upper(Band.name, alias="name")) [{"name": "PYTHONISTAS"}] And also in ``where`` clauses: .. code-block:: python >>> await Band.select().where(Upper(Band.manager.name) == 'GUIDO') [{"name": "Pythonistas"}] ------------------------------------------------------------------------------- 1.5.2 ----- Added an ``Album`` table to the playground, along with some other improvements. Fixed a bug with the ``output(load_json=True)`` clause, when used on joined tables. ------------------------------------------------------------------------------- 1.5.1 ----- Fixed a bug with the CLI when reversing migrations (thanks to @&#8203;metakot for reporting this). Updated the ASGI templates (thanks to @&#8203;tarsil for adding Lilya). ------------------------------------------------------------------------------- 1.5.0 ----- Lots of internal improvements, mostly to support new functionality in Piccolo Admin. ------------------------------------------------------------------------------- 1.4.2 ----- Improved how ``ModelBuilder`` handles recursive foreign keys. ------------------------------------------------------------------------------- 1.4.1 ----- Fixed an edge case with auto migrations. If starting from a table like this, with a custom primary key column: .. code-block:: python class MyTable(Table): id = UUID(primary_key=True) When a foreign key is added to the table which references itself: .. code-block:: python class MyTable(Table): id = UUID(primary_key=True) fk = ForeignKey("self") The auto migrations could fail in some situations. ------------------------------------------------------------------------------- 1.4.0 ----- Improved how ``create_pydantic_model`` handles ``Array`` columns: * Multidimensional arrays (e.g. ``Array(Array(Integer))``) have more accurate types. * ``Array(Email())`` now validates that each item in the list is an email address. * ``Array(Varchar(length=10))`` now validates that each item is the correct length (i.e. 10 in this example). Other changes ~~~~~~~~~~~~~ Some Pylance errors were fixed in the codebase. ------------------------------------------------------------------------------- 1.3.2 ----- Fixed a bug with nested array columns containing ``BigInt``. For example: .. code-block:: python class MyTable(Table): my_column = Array(Array(BigInt)) Thanks to @&#8203;AmazingAkai for reporting this issue. ------------------------------------------------------------------------------- 1.3.1 ----- Fixed a bug with foreign keys which reference ``BigSerial`` primary keys. Thanks to @&#8203;Abdelhadi92 for reporting this issue. ------------------------------------------------------------------------------- 1.3.0 ----- Added the ``piccolo user list`` command - a quick and convenient way of listing Piccolo Admin users from the command line. ``ModelBuilder`` now creates timezone aware ``datetime`` objects for ``Timestamptz`` columns. Updated the ASGI templates. SQLite auto migrations are now allowed. We used to raise an exception, but now we output a warning instead. While SQLite auto migrations aren't as feature rich as Postgres, they work fine for simple use cases. ------------------------------------------------------------------------------- 1.2.0 ----- There's now an alternative syntax for joins, which works really well with static type checkers like Mypy and Pylance. The traditional syntax (which continues to work as before): .. code-block:: python ### Get the band name, and the manager's name from a related table await Band.select(Band.name, Band.manager.name) The alternative syntax is as follows: .. code-block:: python await Band.select(Band.name, Band.manager._.name) Note how we use ``._.`` instead of ``.`` after a ``ForeignKey``. This offers a considerably better static typing experience. In the above example, type checkers know that ``Band.manager._.name`` refers to the ``name`` column on the ``Manager`` table. This means typos can be detected, and code navigation is easier. Other changes ~~~~~~~~~~~~~ * Improve static typing for ``get_related``. * Added support for the ``esmerald`` ASGI framework. ------------------------------------------------------------------------------- 1.1.1 ----- Piccolo allows the user to specify savepoint names which are used in transactions. For example: .. code-block:: python async with DB.transaction() as transaction: await Band.insert(Band(name='Pythonistas')) ### Passing in a savepoint name is optional: savepoint_1 = await transaction.savepoint('savepoint_1') await Band.insert(Band(name='Terrible band')) ### Oops, I made a mistake! await savepoint_1.rollback_to() Postgres doesn't allow us to parameterise savepoint names, which means there's a small chance of SQL injection, if for some reason the savepoint names were generated from end-user input. Even though the likelihood is very low, it's best to be safe. We now validate the savepoint name, to make sure it can only contain certain safe characters. Thanks to @&#8203;Skelmis for making this change. ------------------------------------------------------------------------------- 1.1.0 ----- Added support for Python 3.12. Modified ``create_pydantic_model``, so additional information is returned in the JSON schema to distinguish between ``Timestamp`` and ``Timestamptz`` columns. This will be used for future Piccolo Admin enhancements. ------------------------------------------------------------------------------- 1.0.0 ----- Piccolo v1 is now available! We migrated to Pydantic v2, and also migrated Piccolo Admin to Vue 3, which puts the project in a good place moving forward. We don't anticipate any major issues for people who are upgrading. If you encounter any bugs let us know. Make sure you have v1 of Piccolo, Piccolo API, and Piccolo Admin. ------------------------------------------------------------------------------- 1.0a3 ----- Namespaced all custom values we added to Pydantic's JSON schema for easier maintenance. ------------------------------------------------------------------------------- 1.0a2 ----- All of the changes from 0.120.0 merged into the v1 branch. ------------------------------------------------------------------------------- 0.121.0 ------- Modified the ``BaseUser.login`` logic so all code paths take the same time. Thanks to @&#8203;Skelmis for this. ------------------------------------------------------------------------------- 0.120.0 ------- Improved how ``ModelBuilder`` generates JSON data. The number of password hash iterations used in ``BaseUser`` has been increased to keep pace with the latest guidance from OWASP - thanks to @&#8203;Skelmis for this. Fixed a bug with auto migrations when the table is in a schema. ------------------------------------------------------------------------------- 1.0a1 ----- Initial alpha release of Piccolo v1, with Pydantic v2 support. ------------------------------------------------------------------------------- 0.119.0 ------- ``ModelBuilder`` now works with ``LazyTableReference`` (which is used when we have circular references caused by a ``ForeignKey``). With this table: .. code-block:: python class Band(Table): manager = ForeignKey( LazyTableReference( 'Manager', module_path='some.other.folder.tables' ) ) We can now create a dynamic test fixture: .. code-block:: python my_model = await ModelBuilder.build(Band) ------------------------------------------------------------------------------- 0.118.0 ------- If you have lots of Piccolo apps, you can now create auto migrations for them all in one go: .. code-block:: bash piccolo migrations new all --auto Thanks to @&#8203;hoosnick for suggesting this new feature. The documentation for running migrations has also been improved, as well as improvements to the sorting of migrations based on their dependencies. Support for Python 3.7 was dropped in this release as it's now end of life. ------------------------------------------------------------------------------- 0.117.0 ------- Version pinning Pydantic to v1, as v2 has breaking changes. We will add support for Pydantic v2 in a future release. Thanks to @&#8203;sinisaos for helping with this. ------------------------------------------------------------------------------- 0.116.0 ------- Fixture formatting ~~~~~~~~~~~~~~~~~~ When creating a fixture: .. code-block:: bash piccolo fixtures dump The JSON output is now nicely formatted, which is useful because we can pipe it straight to a file, and commit it to Git without having to manually run a formatter on it. .. code-block:: bash piccolo fixtures dump > my_fixture.json Thanks to @&#8203;sinisaos for this. Protected table names ~~~~~~~~~~~~~~~~~~~~~ We used to raise a ``ValueError`` if a table was called ``user``. .. code-block:: python class User(Table): # ValueError! ... It's because ``user`` is already used by Postgres (e.g. try ``SELECT user`` or ``SELECT * FROM user``). We now emit a warning instead for these reasons: * Piccolo wraps table names in quotes to avoid clashes with reserved keywords. * Sometimes you're stuck with a table name from a pre-existing schema, and can't easily rename it. Re-export ``WhereRaw`` ~~~~~~~~~~~~~~~~~~~~~~ If you want to write raw SQL in your where queries you use ``WhereRaw``: .. code-block:: python >>> Band.select().where(WhereRaw('TRIM(name) = {}', 'Pythonistas')) You can now import it from ``piccolo.query`` to be consistent with ``SelectRaw`` and ``OrderByRaw``. .. code-block:: python from piccolo.query import WhereRaw ------------------------------------------------------------------------------- 0.115.0 ------- Fixture upserting ~~~~~~~~~~~~~~~~~ Fixtures can now be upserted. For example: .. code-block:: bash piccolo fixtures load my_fixture.json --on_conflict='DO UPDATE' The options are: * ``DO NOTHING``, meaning any rows with a matching primary key will be left alone. * ``DO UPDATE``, meaning any rows with a matching primary key will be updated. This is really useful, as you can now edit fixtures and load them multiple times without getting foreign key constraint errors. Schema fixes ~~~~~~~~~~~~ We recently added support for schemas, for example: .. code-block:: python class Band(Table, schema='music'): ... This release contains: * A fix for migrations when changing a table's schema back to 'public' (thanks to @&#8203;sinisaos for discovering this). * A fix for ``M2M`` queries, when the tables are in a schema other than 'public' (thanks to @&#8203;quinnalfaro for reporting this). Added ``distinct`` method to ``count`` queries ``` We recently added support for `COUNT DISTINCT` queries. The syntax is: .. code-block:: python await Concert.count(distinct=\[Concert.start\_date]) The following alternative syntax now also works (just to be consistent with other queries like `select`): .. code-block:: python await Concert.count().distinct(\[Concert.start\_date]) *** </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My40Ni42IiwidXBkYXRlZEluVmVyIjoiNDMuNTkuNCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->
Update dependency piccolo to ~=1.33.0
All checks were successful
Actions / Build (pull_request) Successful in 18s
Actions / Run Tests (pull_request) Successful in 49s
Actions / Lint (pull_request) Successful in 55s
Actions / Build Documentation (pull_request) Successful in 1m9s
b410e777bc
All checks were successful
Actions / Build (pull_request) Successful in 18s
Required
Details
Actions / Run Tests (pull_request) Successful in 49s
Required
Details
Actions / Lint (pull_request) Successful in 55s
Required
Details
Actions / Build Documentation (pull_request) Successful in 1m9s
Required
Details
This pull request can be merged automatically.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin renovate/piccolo-1.x:renovate/piccolo-1.x
git switch renovate/piccolo-1.x
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
cswimr/tidegear!92
No description provided.