Years later with this problem again to share your current answer. I ended up on the Backend-agnostic GUID Type , but I wanted to use the binary instead of CHAR (32). I also wanted to deal with hexadecimal strings directly, not UUID objects for easy printing for user / URL.
import binascii import uuid from sqlalchemy.types import TypeDecorator, BINARY class GUID(TypeDecorator): impl = BINARY def load_dialect_impl(self, dialect): return dialect.type_descriptor(BINARY(16)) def process_bind_param(self, value, dialect): if value is None: return value if not isinstance(value, bytes): if isinstance(value, uuid.UUID): value = value.bytes elif isinstance(value, str): value = binascii.unhexlify(value) else: raise TypeError('Invalid GUID value.') return value def process_result_value(self, value, dialect): if value is None: return value return binascii.hexlify(value).decode('ascii')
I also added a helper function to streamline the UUIDs to improve indexing performance based on this blog post . If you are using MySQL 8, check UUID_TO_BIN () with the swap flag and BIN_TO_UUID ().
def order_uuid(uuid): uuid_str = str(uuid).replace('-', '') ordered_uuid = ''.join([uuid_str[12:16], uuid_str[8:12], uuid_str[0:8], uuid_str[16:]]) return ordered_uuid def revert_order_uuid(o_uuid_str): original_uuid_str = ''.join([o_uuid_str[8:16], o_uuid_str[4:8], o_uuid_str[0:4], o_uuid_str[16:]]) return uuid.UUID(original_uuid_str)
Cedric
source share