首页 > 解决方案 > 使用带有鉴别器的通用关联时如何在父模型上映射公共多态参数

问题描述

下面的示例声明了一个 Mixin,它提供了一个initsubmit扩展来自动在表上创建一个“报告” 。

upload_datetime在此示例中,为了简单起见,它还扩展了模型,但是,它assciation_proxy可能指向提交感兴趣的任何其他属性。

class Submit(db.Model):
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    resource_type = Column(String, nullable=False)
    resource_id = association_proxy("resource", "id")
    upload_datetime = association_proxy("resource", "upload_datetime")
    ...

    __mapper_args__ = {
        'polymorphic_on': resource_type,
    }


class CreatesSubmit():
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.__class__._submit_report_class(resource=self)

    @declared_attr
    def upload_datetime(cls):
        return Column(DateTime, nullable=False, default=dt.now)

    @declared_attr
    def _submit_report_id(cls):
        return Column(ForeignKey('submit.id'))

    @declared_attr
    def _submit_report_class(cls):
        return type(
            f"{cls.__name__}SubmitReport", (Submit,),
            dict(
                __mapper_args__={
                    'polymorphic_identity': cls.__name__.lower(),
                },
            ),
        )

    @declared_attr
    def submit_report(cls):
        return relationship(
            cls._submit_report_class, cascade="all",
            backref=backref("resource", uselist=False),
        )

    def special_methods(self):
        ...

继承这个 Mixin 的所有类都应该创建一个“提交”,它将父级引用为“资源”。例如:

class Benchmark(CreatesSubmit, db.Model):
    ...

benchmark = Benchmark()

允许:

submit = benchmark.submit_report
assert submit.resource == benchmark

但是,我希望能够过滤提交使用upload_datetime签名,例如:

query1 = Benchmark.query.filter(Benchmark.upload_datetime < date)
query2 = Submit.query.filter(Submit.upload_datetime < date)

但是,在query2我得到InvalidRequestErrorMapper 'mapped class Submit->submit' has no property 'resource'

笔记:

标签: pythonsqlalchemy

解决方案


推荐阅读