Skip to content

Instantly share code, notes, and snippets.

@craigdmckenna
Last active January 15, 2023 21:22
Show Gist options
  • Save craigdmckenna/b52cb7207a413672c5576e554c527111 to your computer and use it in GitHub Desktop.
Save craigdmckenna/b52cb7207a413672c5576e554c527111 to your computer and use it in GitHub Desktop.
SQLAlchemy, MySQL 16 bit UUID, Custom Data Type
import UUID
from sqlalchemy.dialects.mysql import BINARY
from sqlalchemy.types import TypeDecorator
class BinaryUUID(TypeDecorator):
'''Optimize UUID keys. Store as 16 bit binary, retrieve as uuid.
inspired by:
http://mysqlserverteam.com/storing-uuid-values-in-mysql-tables/
'''
impl = BINARY(16)
def process_bind_param(self, value, dialect):
try:
return value.bytes
except AttributeError:
try:
return UUID(value).bytes
except TypeError:
# for some reason we ended up with the bytestring
# ¯\_(ツ)_/¯
# I'm not sure why you would do that,
# but here you go anyway.
return value
def process_result_value(self, value, dialect):
return UUID(bytes=value)
from uuid import uuid4
from sqlalchemy import Column
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy_mysql_binary_uuid import BinaryUUID
Base = declarative_base()
class User(Base):
__tablename__ = 'user'
id = Column('id', BinaryUUID, primary_key=True, default=uuid4)
# ...
@kalmik
Copy link

kalmik commented Oct 11, 2020

Actually, this code doesn't work with python 3.8 I had to apply this patch to make it work

--- test.py     2020-10-11 18:00:25.692932356 -0300
+++ test-new.py 2020-10-11 18:00:53.016938534 -0300
@@ -1,4 +1,4 @@
-import UUID
+import uuid
 
 from sqlalchemy.dialects.mysql import BINARY
 from sqlalchemy.types import TypeDecorator
@@ -17,7 +17,7 @@
             return value.bytes
         except AttributeError:
             try:
-                return UUID(value).bytes
+                return uuid.UUID(value).bytes
             except TypeError:
                 # for some reason we ended up with the bytestring
                 # ¯\_(ツ)_/¯
@@ -26,4 +26,4 @@
                 return value
                 
     def process_result_value(self, value, dialect):
-        return UUID(bytes=value)
+        return uuid.UUID(bytes=value)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment