Python 将_table_args__与SQLAlchemy中mixin类的约束相结合
在SQLAlchemy中,我已经阅读了如何在声明声明声明性语句时从不同的mixin组合Python 将_table_args__与SQLAlchemy中mixin类的约束相结合,python,orm,sqlalchemy,declarative,Python,Orm,Sqlalchemy,Declarative,在SQLAlchemy中,我已经阅读了如何在声明声明声明性语句时从不同的mixin组合\uuu table\u args\uuu 我的问题是,这个例子展示了如何在链的末尾(MRO中的最后一个类)实现这一点,但是如果我有这些mixin,并且希望它出现在MyClientMixin或Base类中,以避免将此代码复制到其他类型的mixin中,那么如何实现这一点呢 class LaneCarrierCommitmentSummaryMixin(object): """ Lane Carrier
\uuu table\u args\uuu
我的问题是,这个例子展示了如何在链的末尾(MRO中的最后一个类)实现这一点,但是如果我有这些mixin,并且希望它出现在MyClientMixin
或Base
类中,以避免将此代码复制到其他类型的mixin中,那么如何实现这一点呢
class LaneCarrierCommitmentSummaryMixin(object):
""" Lane Carrier Commitment Summary.
A base class for LCCS to mixin with a client specific class.
"""
__tablename__ = 'lane_carrier_commitment_summary'
__table_args__ = ((UniqueConstraint(['hashmap_key', 'bow'],
name='uq_lane_carrier_commitment_summary_hashmap_key_bow')),)
class MyClientMixin(object):
""" MyClient Mixin class for providing the ETL schema. """
__table_args__ = {'schema': 'myclient_etl'}
class MyClientLaneCarrierCommitmentSummary(LaneCarrierCommitmentSummaryMixin, DateTrackedMixin, MyClientMixin, Base):
pass
我对这个概念有点纠结。这个基类将搜索所有mixin中要添加的
\uuuu table\u args\uuuu
,然后检查当前类中要添加的\uu local\u table\u args\uu
。这样,\uuuuuu local\u table\u args\uuuu
就不会与声明的属性冲突。基类(cls.mro()
)按相反顺序进行检查,以便链下游的混合被较高的混合覆盖
def _process_args(cls, attr, out_args, out_kwargs):
try:
args = getattr(cls, attr)
except AttributeError:
return
if isinstance(args, Mapping): # it's a dictionary
out_kwargs.update(args)
else: # it's a list
if isinstance(args[-1], Mapping): # it has a dictionary at the end
out_kwargs.update(args.pop())
out_args.extend(args)
class Base():
@declared_attr
def __mapper_args__(cls):
args = []
kwargs = {}
for mixin in reversed(cls.mro()):
_process_args(mixin, '__mapper_args__', args, kwargs)
_process_args(mixin, '__local_mapper_args__', args, kwargs)
return kwargs # mapper only takes dict
@declared_attr
def __table_args__(cls):
args = []
kwargs = {}
for mixin in reversed(cls.mro()):
_process_args(mixin, '__table_args__', args, kwargs)
_process_args(cls, '__local_table_args__', args, kwargs)
args.append(kwargs) # [item, item, ..., kwargs]
return tuple(args)
所有mixin都应该像普通一样定义\uuuu table\u args\uuu
,但是从Base
继承的“real”类应该定义\uu local\u table\u args\uu