【问题标题】:SQLAlchemy Bidirectional Association ProxySQLAlchemy 双向关联代理
【发布时间】:2013-08-27 02:01:42
【问题描述】:

我正在尝试使用包含元数据的映射表创建一个简单的多对多关系,该映射表使用 SQLAlchemy 与两端的关联代理表示关系。但是,我似乎无法让它工作。这是我一直在尝试弄清楚的玩具示例:

Base = declarative_base()


def bar_creator(bar):

    _ = FooBar(bar=bar)
    return bar


class Foo(Base):

    __tablename__ = 'foo'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    bars = association_proxy('bar_associations', 'bar',
                             creator=bar_creator)


def foo_creator(foo):

    _ = FooBar(foo=foo)
    return foo


class Bar(Base):

    __tablename__ = 'bar'

    id = Column(Integer, primary_key=True)
    name = Column(String)
    foos = association_proxy('foo_associations', 'foo',
                             creator=foo_creator)


class FooBar(Base):

    __tablename__ = 'fooBar'

    foo_id = Column(Integer, ForeignKey('foo.id'), primary_key=True)
    bar_id = Column(Integer, ForeignKey('bar.id'), primary_key=True)
    bazed = Column(Boolean)
    foo = relationship(Foo, backref='bar_associations')
    bar = relationship(Bar, backref='foo_associations')


Base.metadata.create_all(engine)
make_session = sessionmaker(bind=engine)
session = make_session()
foo0 = Foo(name='foo0')
session.add(foo0)
bar0 = Bar(name='bar0')
foo0.bars.append(bar0)

我添加了 creator 函数,这样我就可以避免编写不适用于我的实际用例(采用单个参数)的 __init__,并在每个函数中都包含了 FooBar 的创建,因为我读过一些被附加的项目需要已经有一个与之关联的链接表实例的文档。我确定我只是遗漏了一些明显的东西(或者甚至可能试图做一些无法完成的事情),但是经过大量的文档和谷歌搜索之后,我无法弄清楚为什么它不起作用.我做错了什么?

【问题讨论】:

  • 你能解释一下究竟是什么不起作用吗?我看不出您为什么需要关联代理的 creator 函数。
  • 无论有没有创作者,它都不起作用,但创作者似乎让它走得更远。当将 bar0 附加到 foo0.bars 时,我从 sqlalchemy/orm/attributes.py",第 1140 行,在 emit_backref_from_collection_append_event child_impl = child_state.manager[key].impl 中收到 foo 的关键错误。

标签: python sqlalchemy associations relationship


【解决方案1】:

您的问题在于creator:它应该返回FooBar 的新实例,而不是barfoo

def bar_creator(value):
    return FooBar(bar=value)

类似foo_creator

【讨论】:

  • 哦,有道理。现在可以了,谢谢。我知道这将是愚蠢而明显的事情......
  • Lambdas 可以提供一种很好的方式来避免编写这些额外的创建者函数,例如:creator=lambda b: FooBar(bar=b)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多