代码之家  ›  专栏  ›  技术社区  ›  diplosaurus

如何使用SQLAlchemy TypeDecorators编译原始SQL

  •  0
  • diplosaurus  · 技术社区  · 7 年前

    uuid.UUID :

    import uuid
    import sqlalchemy
    
    foreign_uuid = '822965bb-c67e-47ee-ad12-a3b060ef79ae'
    qry = Query(MyModel).filter(MyOtherModel.uuid == uuid.UUID(foreign_uuid))
    

    现在我想从SQLAlchemy获取原始postgresql:

    qry.statement.compile(dialect=postgresql.dialect(), compile_kwargs={"literal_binds": True}))
    

    这会产生以下错误: NotImplementedError: Don't know how to literal-quote value UUID('822965bb-c67e-47ee-ad12-a3b060ef79ae')

    这似乎是因为SqlAlchemy只知道如何处理基本类型。 The documentation suggests TypeDecorator 甚至还为guid提供了一个:

    from sqlalchemy.dialects.postgresql import UUID
    import uuid
    
    class GUID(TypeDecorator):
        """Platform-independent GUID type.
    
        Uses PostgreSQL's UUID type, otherwise uses
        CHAR(32), storing as stringified hex values.
    
        """
        impl = CHAR
    
        def load_dialect_impl(self, dialect):
            if dialect.name == 'postgresql':
                return dialect.type_descriptor(UUID())
            else:
                return dialect.type_descriptor(CHAR(32))
    
        def process_bind_param(self, value, dialect):
            if value is None:
                return value
            elif dialect.name == 'postgresql':
                return str(value)
            else:
                if not isinstance(value, uuid.UUID):
                    return "%.32x" % uuid.UUID(value).int
                else:
                    # hexstring
                    return "%.32x" % value.int
    
        def process_result_value(self, value, dialect):
            if value is None:
                return value
            else:
                if not isinstance(value, uuid.UUID):
                    value = uuid.UUID(value)
                return value
    

    但是它没有说怎么做 使用 打字机 . 我需要在我的模型中引用它吗?我能把它提供给 .statement.compile 打电话?

    0 回复  |  直到 7 年前