Skip to content

Releases: piccolo-orm/piccolo

0.69.3

Choose a tag to compare

@dantownsend dantownsend released this 01 Mar 12:48

The where clause now raises a ValueError if a boolean value is passed in by accident. This was possible in the following situation:

await Band.select().where(Band.has_drummer is None)

Piccolo can't override the is operator because Python doesn't allow it, so Band.has_drummer is None will always equal False. Thanks to @trondhindenes for reporting this issue.

We've also put a lot of effort into improving documentation throughout the project.

0.69.2

Choose a tag to compare

@dantownsend dantownsend released this 13 Feb 20:11
  • Lots of documentation improvements, including how to customise BaseUser (courtesy @sinisaos).
  • Fixed a bug with creating indexes when the column name clashes with a SQL keyword (e.g. 'order'). See Pr 433. Thanks to @wmshort for reporting this issue.
  • Fixed an issue where some slots were incorrectly configured (courtesy @ariebovenberg). See PR 426.

0.69.1

Choose a tag to compare

@dantownsend dantownsend released this 04 Feb 10:53

Fixed a bug with auto migrations which rename columns - see PR 423. Thanks to @theelderbeever for reporting this, and @sinisaos for help investigating.

0.69.0

Choose a tag to compare

@dantownsend dantownsend released this 03 Feb 16:58

Added Xpresso as a supported ASGI framework when using piccolo asgi new to generate a web app.

Thanks to @sinisaos for adding this template, and @adriangb for reviewing.

We also took this opportunity to update our FastAPI and BlackSheep ASGI templates.

0.68.0

Choose a tag to compare

@dantownsend dantownsend released this 02 Feb 14:49

Update queries without a where clause

If you try and perform an update query without a where clause you will now get an error:

>>> await Band.update({Band.name: 'New Band'})
UpdateError

If you want to update all rows in the table, you can still do so, but you must pass force=True.

>>> await Band.update({Band.name: 'New Band'}, force=True)

This is a similar to delete queries, which require a where clause or force=True.

It was pointed out by @theelderbeever that an accidental mass update is almost as bad as a mass deletion, which is why this safety measure has been added.

See PR 412.

⚠️ This is a breaking change. If you're doing update queries without a where clause, you will need to add force=True.

JSONB improvements

Fixed some bugs with nullable JSONB columns. A value of None is now stored as null in the database, instead of the JSON string 'null'. Thanks to @theelderbeever for reporting this.

See PR 413.

0.67.0

Choose a tag to compare

@dantownsend dantownsend released this 28 Jan 10:05

create_user

BaseUser now has a create_user method, which adds some extra password validation vs just instantiating and saving BaseUser directly.

>>> await BaseUser.create_user(username='bob', password='abc123XYZ')
<BaseUser: 1>

We check that passwords are a reasonable length, and aren't already hashed. See PR 402.

async first

All of the docs have been updated to show the async version of queries.

For example:

# Previous:
Band.select().run_sync()

# Now:
await Band.select()

Most people use Piccolo in async apps, and the playground supports top level await, so you can just paste in await Band.select() and it will still work. See PR 407.

We decided to use await Band.select() instead of await Band.select().run(). Both work, and have their merits, but the simpler version is probably easier for newcomers.

0.66.1

Choose a tag to compare

@dantownsend dantownsend released this 25 Jan 22:44

In Piccolo you can print out any query to see the SQL which will be generated:

>>> print(Band.select())
SELECT "band"."id", "band"."name", "band"."manager", "band"."popularity" FROM band

It didn't represent UUID and datetime values correctly, which is now fixed (courtesy @theelderbeever). See PR 405.

0.66.0

Choose a tag to compare

@dantownsend dantownsend released this 21 Jan 18:19

Using descriptors to improve MyPy support PR 399.

MyPy is now able to correctly infer the type in lots of different scenarios:

class Band(Table):
    name = Varchar()

# MyPy knows this is a Varchar
Band.name

band = Band()
band.name = "Pythonistas"  # MyPy knows we can assign strings when it's a class instance
band.name  # MyPy knows we will get a string back

band.name = 1  # MyPy knows this is an error, as we should only be allowed to assign strings

You can see it working here in VSCode:

Screenshot 2022-01-21 at 18 17 42

0.65.1

Choose a tag to compare

@dantownsend dantownsend released this 21 Jan 07:50

Fixed bug with BaseUser and Piccolo API.

0.65.0

Choose a tag to compare

@dantownsend dantownsend released this 20 Jan 21:04

The BaseUser table hashes passwords before storing them in the database.

When we create a fixture from the BaseUser table (using piccolo fixtures dump), it looks something like:

{
    "id": 11,
    "username": "bob",
    "password": "pbkdf2_sha256$10000$abc123"
}

When we load the fixture (using piccolo fixtures load) we need to be careful in case BaseUser tries to hash the password again (it would then be a hash of a hash, and hence incorrect). We now have additional checks in place to prevent this.

Thanks to @mrbazzan for implementing this, and @sinisaos for help reviewing.