查询时的AttributeError:"InstrumentedAttribute"对象和"Comparator"都没有属性

Ble*_*ers 35 python sqlalchemy attributeerror

以下代码:

Base = declarative_base()
engine = create_engine(r"sqlite:///" + r"d:\foo.db",
                       listeners=[ForeignKeysListener()])
Session = sessionmaker(bind = engine)
ses = Session()

class Foo(Base):
    __tablename__ = "foo"
    id = Column(Integer, primary_key=True)
    name = Column(String, unique = True)

class Bar(Base):
    __tablename__ = "bar"
    id = Column(Integer, primary_key = True)
    foo_id = Column(Integer, ForeignKey("foo.id"))

    foo = relationship("Foo")


class FooBar(Base):
    __tablename__ = "foobar"
    id = Column(Integer, primary_key = True)
    bar_id = Column(Integer, ForeignKey("bar.id"))

    bar = relationship("Bar")



Base.metadata.create_all(engine)
ses.query(FooBar).filter(FooBar.bar.foo.name == "blah")
Run Code Online (Sandbox Code Playgroud)

给我这个错误:

AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with FooBar.bar has an attribute 'foo'
Run Code Online (Sandbox Code Playgroud)

关于为什么会发生这种情况的任何解释,以及如何实现这样的事情的指导?

ost*_*ach 45

这是因为您尝试barFooBar类而不是FooBar实例进行访问.该FooBar班没有任何bar与它-关联的对象bar仅仅是一个SQLAlchemy的InstrumentedAttribute.这就是你得到错误的原因:

AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with FooBar.bar has an attribute 'foo'
Run Code Online (Sandbox Code Playgroud)

通过FooBar.bar.foo.name在sqlalchemy查询外部键入,您将收到相同的错误.

解决方案是Foo直接调用该类:

ses.query(FooBar).join(Bar).join(Foo).filter(Foo.name == "blah")
Run Code Online (Sandbox Code Playgroud)

  • 如果表与`Foo'有多个关系怎么办? (17认同)
  • 我觉得这个答案错了​​!它发出这样的:`SELECT foobar.id AS foobar_id,foobar.bar_id AS foobar_bar_id FROM foobar,foo WHERE foo.name =?`,它在进行过滤之前不加入表. (2认同)

Ble*_*ers 26

我无法从技术上解释发生了什么,但您可以通过使用以下方法解决此问题:

ses.query(FooBar).join(Foobar.bar).join(Bar.foo).filter(Foo.name == "blah")
Run Code Online (Sandbox Code Playgroud)

  • 您可以在文档中理解它的工作原理:http://docs.sqlalchemy.org/en/rel_0_9/orm/tutorial.html#querying-with-joins (3认同)
  • 这是正确的,接受的答案是错误的,因为它没有在外键上连接表。您实际上可以从此答案中删除“.bar”和“.foo”,它仍然有效。 (2认同)

tok*_*fsj 5

我遇到了同样的错误Neither 'InstrumentedAttribute' object nor 'Comparator' has an attribute,但就我而言,问题是我的模型包含一个名为 的列query,它覆盖了内部属性model.query

我决定将该列重命名为query_text并消除了错误。另外,传递name=参数列方法会工作:query = db.Column(db.TEXT, name='query_text')