Skip to content

Commit 039608a

Browse files
committed
add SQLAlchemy example
1 parent ebd7318 commit 039608a

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed

examples/sqlalchemy.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
from typing import Optional
2+
3+
from sqlalchemy import types
4+
from sqlalchemy.util import generic_repr
5+
from typeid import TypeID, from_uuid
6+
7+
8+
class TypeIDType(types.TypeDecorator):
9+
"""
10+
A SQLAlchemy TypeDecorator that allows storing TypeIDs in the database.
11+
The prefix will not be persisted, instead the database-native UUID field will be used.
12+
At retrieval time a TypeID will be constructed based on the configured prefix and the
13+
UUID value from the database.
14+
15+
Usage:
16+
# will result in TypeIDs such as "user_01h45ytscbebyvny4gc8cr8ma2"
17+
id = mapped_column(
18+
TypeIDType("user"),
19+
primary_key=True,
20+
default=lambda: TypeID("user")
21+
)
22+
"""
23+
impl = types.Uuid
24+
25+
cache_ok = True
26+
27+
prefix: Optional[str]
28+
29+
def __init__(self, prefix: Optional[str], *args, **kwargs):
30+
self.prefix = prefix
31+
super().__init__(*args, **kwargs)
32+
33+
def __repr__(self) -> str:
34+
# Customize __repr__ to ensure that auto-generated code e.g. from alembic includes
35+
# the right __init__ params (otherwise by default prefix will be omitted because
36+
# uuid.__init__ does not have such an argument).
37+
return generic_repr(
38+
self,
39+
to_inspect=TypeID(self.prefix),
40+
)
41+
42+
def process_bind_param(self, value: TypeID, dialect):
43+
if self.prefix is None:
44+
assert value.prefix is None
45+
else:
46+
assert value.prefix == self.prefix
47+
48+
return value.uuid
49+
50+
def process_result_value(self, value, dialect):
51+
return from_uuid(value, self.prefix)

0 commit comments

Comments
 (0)