Conversation
piccolo/columns/defaults/uuid.py
Outdated
There was a problem hiding this comment.
Cockroach doesn't have UUID 7 support yet (as far as I can see).
I guess we can just raise NotImplemented for now.
| def postgres(self): | ||
| return "uuid_generate_v4()" | ||
| """ | ||
| Historically we had to use `uuid_generate_v4()` from the `uuid-ossp` | ||
| extension. | ||
|
|
||
| Since Postgres 13 there is a built-in `gen_random_uuid` function which | ||
| generates UUID v4 values. | ||
|
|
||
| In Postgres 18, `uuidv4` was added, which is the same as | ||
| `gen_random_uuid`, but more precisely named. We will move to this at | ||
| some point in the future. | ||
|
|
||
| """ | ||
| return "gen_random_uuid()" |
There was a problem hiding this comment.
I'm going to split these changes out into a separate PR.
|
@dantownsend Just one question. How would you solve this Postgres error without having to install some |
I was going to just put in the docs that it's Postgres 18 only for now. I think there are some scripts out there somewhere which would allow us to use uuid 7 on older versions. If you can find one I'm not averse to using it (it might also solve the problem for CockroachDB too). |
|
I tried this custom function and by adding this function I was able to pass the tests. I don't know if this is the correct way to use it, but I added that custom function to postgres.py like this if current_transaction:
await current_transaction.connection.execute(
"""
-- Source: https://gist.github.com/kjmph/5bd772b2c2df145aa645b837da7eca74
create or replace function uuidv7()
returns uuid
as $$
begin
-- use random v4 uuid as starting point (which has the same variant we need)
-- then overlay timestamp
-- then set version 7 by flipping the 2 and 1 bit in the version 4 string
return encode(
set_bit(
set_bit(
overlay(uuid_send(gen_random_uuid())
placing substring(int8send(floor(extract(epoch from clock_timestamp()) * 1000)::bigint) from 3)
from 1 for 6
),
52, 1
),
53, 1
),
'hex')::uuid;
end
$$
language plpgsql
volatile;
"""
)
response = await current_transaction.connection.fetch(ddl)I also tried those changes in the app using |
Thanks for this. I'm still a bit undecided how deep to go on this. Maybe we add this to the docs if people want to use UUID7 on older versions of Postgres. |
|
Here is another example of a custom Postgres uuid v7 function (from Piccolo issues). What I like about |
| log_queries: bool = False, | ||
| log_responses: bool = False, | ||
| extra_nodes: Optional[Mapping[str, PostgresEngine]] = None, | ||
| polyfills: list[Literal["uuidv7"]] = [], |
There was a problem hiding this comment.
This is great, really clever. Can you add a description of polyfills to the PostgresEngine docstring?
| @property | ||
| def cockroach(self): | ||
| """ | ||
| Unfortunately CockroachDB doesn't current support this. | ||
| """ | ||
| raise NotImplementedError() |
There was a problem hiding this comment.
I don't know if it's a good idea, but since Cockroach doesn't natively support uuidv7, we can generate default values from Python. Something like this
@property
def cockroach(self):
return QueryString(f"'{uuid7()}'")I tried it locally with Cockroach and it worked. A valid uuidv7 is generated and saved in the database. Piccolo unittests also pass.
There was a problem hiding this comment.
Ideally I'd love to find a script which provides UUID7 for Cockroach. I can't get the Postgres one to work with Cockroach:
ERROR: encode(): set_bit(): set_bit(): unknown signature: overlay(bytes, bytes, int, int)
SQLSTATE: 42883
HINT: No function matches the given name and argument types. You might need to add explicit type casts.
Even though this works:
@property
def cockroach(self):
return QueryString(f"'{uuid7()}'")We need a function which generates the UUID within the database itself. For now I think I'll just leave out Cockroach support until they natively support it.
There was a problem hiding this comment.
Never mind, it was just an idea. I haven't found any examples of custom functions that will work in Cockroach, which means it's not that common in Cockroach. You are right that it should be left as it is and wait for the native implementation.
There was a problem hiding this comment.
Yeah, it's hard with Cockroach because it's mostly Postgres compatible, but when it comes to functions etc it's missing a few.
There was a problem hiding this comment.
I'm tempted to not even support older versions of Postgres and Python with uuid7, just because it relies on other people's code (the uuid7 Python backport, and the Postgres function), which are under different licenses. It becomes a bit of a mess.
So if people want to use it, they just have to use Python 3.14 and Postgres 18.
We'll just make the tests only run for that version of Python and Postgres.
There was a problem hiding this comment.
It's actually a good idea and the code will be much simpler. With this we only rely on the Python 3.14 standard library and the native Postgres 18 implementation. That should be emphasized in the documentation.
Resolves #1280