带有 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.py
和 c.py
,但我也需要排除那里的关系键。在这种情况下如何避免循环导入?
- 我知道可以选择将所有内容都包含在一个模块中,但我将其作为最后的选择。
你说你的问题是你不能"import BSchema
into a.py and c.py",但似乎ASchema
和CSchema
依赖的是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
)
注意
这里 "exclude" 是 fields.Nested()
的关键字参数,而不是嵌套 Schema
和
的关键字参数
fields.Nested()
第一个参数应该是 Schema
class 或 Schema
class名称,不是一个Schema
实例。
所以问题来了。假设我有三个模式模块。例如。
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.py
和 c.py
,但我也需要排除那里的关系键。在这种情况下如何避免循环导入?
- 我知道可以选择将所有内容都包含在一个模块中,但我将其作为最后的选择。
你说你的问题是你不能"import BSchema
into a.py and c.py",但似乎ASchema
和CSchema
依赖的是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
)
注意
这里 "exclude" 是
fields.Nested()
的关键字参数,而不是嵌套Schema
和 的关键字参数
fields.Nested()
第一个参数应该是Schema
class 或Schema
class名称,不是一个Schema
实例。