在模型上使用查询类方法时如何避免在Peewee中进行循环导入?

问题描述 投票:0回答:1

[使用Peewee时,我遵循Create "query methods" in Peewee Models Python答案的建议:

class Person(Model):
    name = CharField()
    age = IntegerField()

    @classmethod
    def adults(cls):
        return cls.select().where(cls.age > 18)

我为所有查询创建类方法,以使模型保持“胖”状态,并使其他所有内容保持“稀疏”状态。现在,我介绍了一个外键,并且我在尝试这种方法,因为Peewee要求我直接在查询中使用模型类:

class Metric(Model):
    person = ForeignKeyField(Person, backref='metrics')
    name = CharField()
    value = IntegerField()

其他文件:

class Person(Model):
    name = CharField()
    age = IntegerField()

    @classmethod
    def popular(cls, min_likes):
        return cls.select(cls, Metric).join(Metric).where(Metric.name == 'likes', Metric.value > min_likes)

这将不起作用,因为Metric的定义取决于Person,反之亦然,导致循环导入。该文档有一个Circular foreign key dependencies部分,其中类似情况的解决方案是DeferredForeignKey,但我不喜欢它,因为它增加了代码开销(需要在任何地方手动创建外键),并且因为我的应用程序正在使用SQLite-文档明确声明以下内容:

因为SQLite对更改表的支持有限,所以在创建表后不能将外键约束添加到表中。

如果我理解正确,那实际上意味着我实际上将完全失去FK约束。不过,我需要约束,该应用程序依赖于缺少对应项的记录会引发异常的事实。

我正在忽略其他解决方法吗?毕竟,在Peewee中推荐这样的胖模型吗?我喜欢它,但是这让我陷入了模型设计的死胡同。文档甚至说:

我个人的看法是,圆形外键是代码的味道,应该进行重构(例如,通过添加中间表)。


Update:我最初更新了问题,无意中省略了主要细节:我正在处理循环imports,而不仅仅是类之间的dependencies。如果我将类并置到一个文件中,它将可以正常工作,因为Python仅在调用它们时才在类方法中解析名称,但这不是我要解决的问题,我想将类保留在单独的模块中。

python sqlite foreign-keys peewee
1个回答
0
投票
我认为您不了解Python作用域。引用方法体内的相关模型没有错,例如:]

# Move metric below Person. class Person(Model): name = CharField() age = IntegerField() @classmethod def popular(cls, min_likes): return cls.select(cls, Metric).join(Metric).where(Metric.name == 'likes', Metric.value > min_likes) class Metric(Model): person = ForeignKeyField(Person, backref='metrics') name = CharField() value = IntegerField()

或者,您可以使用为此目的而[构建的DeferredForeignKey
© www.soinside.com 2019 - 2024. All rights reserved.