SQLAlchemy with_variant()不尊重自定义列类型

时间:2017-05-09 11:56:18

标签: python database sqlalchemy

我尝试使用SQLAlchemy的with_variant()为方言变体使用自定义列(装饰类型),但bind_expressioncol_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_expressioncol_expression来进行SQL级别的更改以应用这些函数。

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

现实世界的用例是我尝试使用变种类型申请使用COMPRESS()UNCOMPRESS()的MySQL,而使用SQLite进行本地测试则数据存储不变

SQLAlchemy版本:1.1.9

转载于:

  • Mac OS X 10.11.6上的Python 2.7.10
  • Debian Wheezy上的Python 2.7.3

0 个答案:

没有答案