ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

python – 将__table_args__与SQLAlchemy中的mixin类的约束相结合

2019-06-12 11:44:45  阅读:1113  来源: 互联网

标签:python orm sqlalchemy declarative


在SQLAlchemy中,我已经阅读了如何在声明声明时组合来自不同mixin的__table_args__.

Combining Table/Mapper Arguments from Multiple Mixins

我的问题是,该示例显示了如何在链的末尾(MRO中的最终类)完成此操作,但如果我有这些Mixins并希望它出现在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以添加__table_args__,然后检查当前类以添加__local_table_args__.这样,__ local_table_args__不与声明的attr冲突.以相反的顺序检查基类(cls.mro()),以便链中较低的mixins被更高的mixin覆盖.

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都应该正常定义__table_args__,但是从Base继承的“real”类应该定义__local_table_args__.

标签:python,orm,sqlalchemy,declarative
来源: https://codeday.me/bug/20190612/1225612.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有