嵌套的 Marshmallow 字段和 Sqlalchemy 关系
Nested Marshmallow fields and Sqlalchemy relationships
在我的 sqlalchemy 类 我有以下 类:
class FooBar(Model):
__tablename__ = ‘foobar’
id = Column('id', Integer, primary_key=True)
foonr = Column('foonr', Integer, ForeignKey('foo.nr'), nullable=False)
barnr = Column('barnr', String, ForeignKey('bar.nr'), nullable=False)
class Foo(Model):
__tablename__ = ‘foo’
nr = Column('nr', Integer, primary_key=True)
foo_name = Column(‘name’,String)
class Bar(Model):
__tablename__ = ‘bar’
nr = Column('nr', Integer, primary_key=True)
bar_name = Column(‘name’,String)
foo_bar = relationship('foobar', uselist=False)
当我尝试将 类 Foo 或 Bar 嵌套在 FooBar 的 Marshmallow 模式中时,我没有得到任何结果(字典没有任何对 类 Foo 或酒吧)。
class FooBarSchema(Schema):
id = fields.Int()
foo = fields.Nested('FooSchema', many=False)
bar = fields.Nested('BarSchema', many=False)
如何在 FooBarSchema 的结果中获取 Foo 和 Bar 类?
好的...我会为您提供解决问题的方法。
class FooBar(Model):
__tablename__ = 'foobar'
id = Column('id', Integer, primary_key=True)
foonr = Column('foonr', Integer, ForeignKey('foo.nr'), nullable=False)
barnr = Column('barnr', String, ForeignKey('bar.nr'), nullable=False)
foo = relationship("Foo", uselist=False)
bar = relationship("Bar", uselist=False)
class FooBarSchema(Schema):
id = fields.Int()
foo = fields.Nested('FooSchema', many=False)
bar = fields.Nested('BarSchema', many=False)
但是分析你的代码我认为我们可以让它更像 pythonic。
当且仅当您在关联 table 中没有额外数据时,我们可以更改一些内容。
查看 SQLAlchemy 文档中的 Many To Many 关系,我们可以使用 relationship()
的 secondary
参数。
我们必须保持 class 和您目前拥有的 class Bar
一样:
class Bar(Model):
__tablename__ = 'bar'
nr = Column('nr', Integer, primary_key=True)
bar_name = Column('name',String)
foos = relationship("Foo", secondary="foobar", backref="bars")
所以在 Bar.foos
中我们有一个 Foo
对象的列表,并且 backref
也使得在 Foo.bars
中有一个 Bar
列表成为可能.
现在我们必须配置 BarSchema
和 FooSchema
classes.
class FooSchema(Schema):
nr = fields.Int()
foo_name = fields.Str()
bars = fields.Nested('BarSchema', exclude=('foos',), many=True)
class BarSchema(Schema):
nr = fields.Int()
bar_name = fields.Str()
foos = fields.Nested('FooSchema', exclude=('bars',), many=True)
exclude
是为了避免递归问题。
在我的 sqlalchemy 类 我有以下 类:
class FooBar(Model):
__tablename__ = ‘foobar’
id = Column('id', Integer, primary_key=True)
foonr = Column('foonr', Integer, ForeignKey('foo.nr'), nullable=False)
barnr = Column('barnr', String, ForeignKey('bar.nr'), nullable=False)
class Foo(Model):
__tablename__ = ‘foo’
nr = Column('nr', Integer, primary_key=True)
foo_name = Column(‘name’,String)
class Bar(Model):
__tablename__ = ‘bar’
nr = Column('nr', Integer, primary_key=True)
bar_name = Column(‘name’,String)
foo_bar = relationship('foobar', uselist=False)
当我尝试将 类 Foo 或 Bar 嵌套在 FooBar 的 Marshmallow 模式中时,我没有得到任何结果(字典没有任何对 类 Foo 或酒吧)。
class FooBarSchema(Schema):
id = fields.Int()
foo = fields.Nested('FooSchema', many=False)
bar = fields.Nested('BarSchema', many=False)
如何在 FooBarSchema 的结果中获取 Foo 和 Bar 类?
好的...我会为您提供解决问题的方法。
class FooBar(Model):
__tablename__ = 'foobar'
id = Column('id', Integer, primary_key=True)
foonr = Column('foonr', Integer, ForeignKey('foo.nr'), nullable=False)
barnr = Column('barnr', String, ForeignKey('bar.nr'), nullable=False)
foo = relationship("Foo", uselist=False)
bar = relationship("Bar", uselist=False)
class FooBarSchema(Schema):
id = fields.Int()
foo = fields.Nested('FooSchema', many=False)
bar = fields.Nested('BarSchema', many=False)
但是分析你的代码我认为我们可以让它更像 pythonic。
当且仅当您在关联 table 中没有额外数据时,我们可以更改一些内容。
查看 SQLAlchemy 文档中的 Many To Many 关系,我们可以使用 relationship()
的 secondary
参数。
我们必须保持 class 和您目前拥有的 class Bar
一样:
class Bar(Model):
__tablename__ = 'bar'
nr = Column('nr', Integer, primary_key=True)
bar_name = Column('name',String)
foos = relationship("Foo", secondary="foobar", backref="bars")
所以在 Bar.foos
中我们有一个 Foo
对象的列表,并且 backref
也使得在 Foo.bars
中有一个 Bar
列表成为可能.
现在我们必须配置 BarSchema
和 FooSchema
classes.
class FooSchema(Schema):
nr = fields.Int()
foo_name = fields.Str()
bars = fields.Nested('BarSchema', exclude=('foos',), many=True)
class BarSchema(Schema):
nr = fields.Int()
bar_name = fields.Str()
foos = fields.Nested('FooSchema', exclude=('bars',), many=True)
exclude
是为了避免递归问题。