我遇到sqlalchemy和旧数据库的问题。假设我有类似的模型
class A(Base):
foo = Column(String)
modified_at = Column(DateTime, default=func.now, onupdate=func.now())
class B(Base):
bar = Column(String)
modified_at = Column('SOME_NAME', DateTime, default=func.now, onupdate=func.now())
正如您所看到的,modified_at字段中存在代码重复。这两个类都有modified_at字段来跟踪上次修改的时间,但具有不同的列名。
这可以使用元类来解决,但它实际上需要基本相同数量的代码来传递列名,因为它与使用代码重复的解决方案一样(特别是在python2中,因为在python2中你不能将参数传递给元类)容易)
所以我想到的是使用decorate类
def modified_at(col_name=None):
def decorator(cls):
cls.modified_at = Column(col_name, Datetime) # etc
return cls
return decorator
@modified_at('SOME_NAME')
class B(Base):
bar = Column(String)
但是这在实例化B时会给我错误(bar ='某些值')
TypeError decorator() got an unexpected keyword argument 'bar'
答案 0 :(得分:0)
你仍然可以使用mixin。来自SQLAlchemy文档:http://docs.sqlalchemy.org/en/latest/orm/extensions/declarative/mixins.html#mixing-in-columns
class TimestampMixin(object):
created_at = Column(DateTime, default=func.now())
class MyModel(TimestampMixin, Base):
__tablename__ = 'test'
id = Column(Integer, primary_key=True)
name = Column(String(1000))
相反,定义一个返回mixin的函数:
def custom_mixin(param):
class MyMixin(object):
created_at = Column(DateTime, param, default=func.now())
return MyMixin
class MyModel(custom_mixin('foobar'), Base):
__tablename__ = 'test'
id = Column(Integer, primary_key=True)
name = Column(String(1000))
您也可以定义一个函数来返回已配置的Column()对象,并正常配置该类。