我尝试使用SQLAlchemy的with_variant()
为方言变体使用自定义列(装饰类型),但bind_expression
和col_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
和col_expression
来进行SQL级别的更改以应用这些函数。
显然我并不期望INSERT查询在SQLite中实际工作,因为这些函数不存在,但是我用这种方式编写了这个例子来证明SQL级别的覆盖是永远不会的被叫。
现实世界的用例是我尝试使用变种类型申请使用COMPRESS()
和UNCOMPRESS()
的MySQL,而使用SQLite进行本地测试则数据存储不变
SQLAlchemy版本:1.1.9
转载于: