SQLAlchemy按自定义列选择

时间:2017-07-25 09:54:40

标签: python sqlalchemy

我有一个带有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以使用此功能,那将非常有用。

或者做这样的风格很糟糕?

2 个答案:

答案 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())
相关问题