-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
make compatible with sqlalchemy #5
Conversation
Hello @beheh. |
Sure! While I'm not sure yet whether my project will be open source, I'll post my current version here for now: from typeid import TypeID, base32, from_uuid as typeid_from_uuid
def get_uuid_from_type_id(type_id: TypeID) -> UUID:
return UUID(bytes=bytes(base32.decode(type_id.suffix)))
class TypeIDType(types.TypeDecorator):
impl = types.Uuid
cache_ok = True
prefix: Optional[str]
def __init__(self, prefix: Optional[str], *args, **kwargs):
self.prefix = prefix
super().__init__(*args, **kwargs)
def process_bind_param(self, value: TypeID, dialect):
if self.prefix is None:
assert value.prefix is None
else:
assert value.prefix == self.prefix
return get_uuid_from_type_id(value)
def process_result_value(self, value, dialect):
return typeid_from_uuid(value, self.prefix) This TypeDecorator can then be used as a column type, storing the suffix in the database a UUID field, and then we simply assert the prefix during conversion into the DB. One thing you may notice is that I'm manually extracting the UUID - I didn't find a way to do this using typeid-python's API. |
Looks nice!
I presume these steps would positively affect our project 😌 |
@beheh Sorry, forgot to tag you 😅 |
Hello @beheh |
@akhundMurad I was away from my machine and pushed my remaining code now. I've unmarked as draft. |
This PR was motivated by an issue I faced while I was trying to use TypeIDs as primary keys in a SQLAlchemy-based project, because SQLAlchemy was unable to index rows by their id (
TypeError: unhashable type: 'TypeID'
).This PR does a few things:
TypeID.uuid
property for easy extraction of the UUID for storage in SQLAlchemyexamples/sqlalchemy.py
with a simple example on how to use a TypeID as a SQLAlchemy column typeImplementation details
This PR makes TypeID hashable1 by implementing a
__hash__
function that wraps prefix and suffix. Hashing the prefix will simply hash the string (or None), and hashing the suffix will simply defer to the UUID hash implementation2. This implementation should have no interaction with the TypeID spec, because this type of hashing is only relevant within Python specifically to interoperate with other Python types. To my knowledge there is no common cross-language definition of the hashing algorithm.Footnotes
https://docs.python.org/3.11/glossary.html#term-hashable ↩ ↩2
https://github.com/python/cpython/blob/afa7b0d743d9b7172d58d1e4c28da8324b9be2eb/Lib/uuid.py#L268-L269 ↩