我有一个带有UUID格式自定义ID的SQLAlchemy模型
class Email(Base):
__tablename__ = 'Email'
id = Column(UUID(), primary_key=True, default=uuid.uuid4)
raw_email = Column(Text)
当我尝试通过ID
获取某个对象时session.query(Email).get("0c7a2a97-c93b-4f26-9408-25d2bf597bc0")
它会返回错误
can't escape UUID to binary
我理解自定义ID中的问题,因为ID是UUID类型,但是我可以创建一些预处理器或其他类似的东西,这使我有机会使用str
选择对象。因为每次我需要选择一些对象时将str转换为UUID会很烦人
我为此转换创建了自己的函数
def str_to_uuid(value):
uuid = UUID()
return uuid.process_bind_param(value)
如果我可以装饰ID以使用此功能,那将非常有用。
或者做这样的风格很糟糕?
答案 0 :(得分:0)
我理解为什么我有这个问题。
class UUID(types.TypeDecorator):
impl = types.LargeBinary
def __init__(self):
self.impl.length = 16
types.TypeDecorator.__init__(self, length=self.impl.length)
def process_bind_param(self, value, dialect=None):
if value and isinstance(value, uuid.UUID):
return value.bytes
elif value and isinstance(value, str):
return uuid.UUID(value)
elif value:
raise ValueError('value %s is not a valid uuid.UUID' % value)
else:
return None
def process_result_value(self, value, dialect=None):
if value:
return uuid.UUID(bytes=value)
else:
return None
def is_mutable(self):
return False
这是我对UUID Column类型的实现。而我的错误在于
process_bind_param
。我忘了将bytes
添加到
elif value and isinstance(value, str):
return uuid.UUID(value)
所以当我将方法改为
时,我解决了这个问题def process_bind_param(self, value, dialect=None):
...
elif value and isinstance(value, str):
return uuid.UUID(value).bytes
elif value:
raise ValueError('value %s is not a valid uuid.UUID' % value)
else:
return None
也许对某人有帮助。
答案 1 :(得分:0)
我在flask-sqlalchemy中一直使用它,似乎没有问题。
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy import desc, func
class User(db.Model):
__tablename__ = 'users'
id = db.Column(UUID, primary_key=True,
server_default=func.uuid_generate_v4())