带有 Marshmallow 嵌套关系的循环导入

Circular import with Marshmallow nested relations

所以问题来了。假设我有三个模式模块。例如。

a.py:

from models import A

class ASchema(ModelSchema):
    class Meta:
        model = A

    text = fields.String(required=True)
    bs = fields.Nested('BSchema', many=True, dump_only=True)

c.py:

from models import C

class CSchema(ModelSchema):
    class Meta:
        model = C

    text = fields.String(required=True)
    bs = fields.Nested('BSchema', many=True, dump_only=True)

b.py:

from models import B

class BSchema(ModelSchema):
    class Meta:
        model = B

    text = fields.String(required=True)
    as = fields.Nested(ASchema(exclude=ASchema.Meta.model.relations_keys), many=True, dump_only=True)
    cs = fields.Nested(CSchema(exclude=CSchema.Meta.model.relations_keys), many=True, dump_only=True)

问题是我无法将 BSchema 导入 a.pyc.py,但我也需要排除那里的关系键。在这种情况下如何避免循环导入?

你说你的问题是你不能"import BSchema into a.py and c.py",但似乎ASchemaCSchema依赖的是classB (在您的代码段中的任何地方都没有定义),而不是 class BSchema,因此您的选择之一是将 "model" class 定义与 "ModelSchema" 分开class 定义 - 所以你会有包 "a"、"b" 和 "c",每个包都有子模块 "models.py" 和 "schemas.py",以及 "schemas.py" 模块依赖于 "models" 但 "models" 不依赖于 "schemas".

这就是说,当你有如此紧密的耦合时,这通常意味着你的 classes 确实属于同一个模块......

编辑:看起来你已经在一个不同的模块中有了你的模型,所以我真的不明白是什么阻止你直接在 "schema" 模块中引用模型,即:

# a.py
from wherever import ModelSchema, fields
from models import A, B

class ASchema(ModelSchema):
    class Meta:
        model = A

    text = fields.String(required=True)
    bs = fields.Nested(
            'BSchema', 
            exclude=B.relations_keys,
            many=True, 
            dump_only=True
            )

# c.py
from wherever import ModelSchema, fields
from models import C, B

class ASchema(ModelSchema):
    class Meta:
        model = C

    text = fields.String(required=True)
    bs = fields.Nested(
            'BSchema', 
            exclude=B.relations_keys,
            many=True, 
            dump_only=True
            )

# b.py
from wherever import ModelSchema, fields
from models import A, B, C

class BSchema(ModelSchema):
    class Meta:
        model = B

    text = fields.String(required=True)
    as = fields.Nested(
            "ASchema", 
            exclude=A.relations_keys, 
            many=True, 
            dump_only=True
            )
    cs = fields.Nested(
             "CSchema", 
             exclude=C.relations_keys, 
             many=True, 
             dump_only=True
             )

注意

  1. 这里 "exclude" 是 fields.Nested() 的关键字参数,而不是嵌套 Schema

  2. 的关键字参数
  3. fields.Nested() 第一个参数应该是 Schema classSchema class名称,不是一个Schema实例