Combining __table_args__ with constraints from mixin classes in SQLAlchemy

In SQLAlchemy, I read about how to combine __table_args__from different mixins when declaring declarative.

Combining Table / Mapper Arguments from Multiple Mixers

I had a question: an example shows how this is done at the end of the chain (the final class in the MRO), but how to achieve this if I had these Mixins and wanted it to happen in MyClientMixinor Baseto avoid duplication of this code for others types of mixins?

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

I'm struggling a bit with this concept.

+4
source share
1 answer

mixins __table_args__ , __local_table_args__ . , __local_table_args__ attr. (cls.mro()) , , , .

def _process_args(cls, attr, out_args, out_kwargs):
    try:
        args = getattr(cls, attr)
    except AttributeError:
        return

    if isinstance(args, Mapping):  # it a dictionary
        out_kwargs.update(args)
    else:  # it 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)

__table_args__ , "real", Base, __local_table_args__.

+7

Source: https://habr.com/ru/post/1538911/


All Articles