SQLAlchemy with_variant()不符合自定义列类型

2024-06-17 13:15:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图使用SQLAlchemy的with_variant()为方言变体使用一个自定义列(修饰类型),但是bind_expression和{}的实现从未被调用。在

这是一个小型测试案例,演示了这一点:

#!/usr/bin/env python
import sqlalchemy
import sqlalchemy.ext.declarative
import sqlalchemy.orm
import sqlalchemy.types


class CompressedLargeBinary(sqlalchemy.types.TypeDecorator):
    impl = sqlalchemy.types.LargeBinary

    def bind_expression(self, bindvalue):
        # No compress function in SQLite but we'll never get here
        return sqlalchemy.func.compress(bindvalue, type_=self)

    def column_expression(self, col):
        # No uncompress function in SQLite but we'll never get here
        return sqlalchemy.func.uncompress(col, type_=self)


SometimesCompressedLargeBinary = sqlalchemy.types.LargeBinary().with_variant(CompressedLargeBinary(), "sqlite")

Base = sqlalchemy.ext.declarative.declarative_base()


class Foo(Base):
    __tablename__ = "foo"

    id = sqlalchemy.Column(sqlalchemy.Integer, nullable=False, primary_key=True)
    bar = sqlalchemy.Column("baz", SometimesCompressedLargeBinary, nullable=False)

    def __init__(self, bar):
        self.id = None
        self.bar = bar


def main():
    engine = sqlalchemy.create_engine('sqlite:///./file.db')
    connection = engine.connect()
    Session = sqlalchemy.orm.sessionmaker(bind=engine)
    session = Session()

    Base.metadata.drop_all(engine)
    Base.metadata.create_all(engine)

    model = Foo("quux")
    session.add(model)
    session.commit()


if __name__ == "__main__":
    main()

预期的行为是INSERT查询失败,因为它使用了SQLite中不可用的函数,但是bind_expression和{}永远不会被调用来进行SQL级别的更改以应用这些函数。在

显然,我并不期望INSERT查询在SQLite中实际工作,因为那些函数并不存在,但是我用这种方式编写了示例,以证明SQL级别的重写永远不会被调用。在

实际的用例是,我尝试将一个变量类型应用于MySQL,它使用COMPRESS()和{},而对于使用SQLite的本地测试,数据存储不变。在

SQLAlchemy版本:1.1.9

转载于:

  • Mac OS X 10.11.6上的Python 2.7.10
  • Debian Wheezzy上的Python2.7.3

Tags: 函数importselfsqlitebasesqlalchemybindmain