查询时的AttributeError:“仪器化属性”'对象也不是'比较器'有一个属性

时间:2013-05-16 13:46:33

标签: 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")

给了我这个错误:

AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with FooBar.bar has an attribute 'foo'

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

4 个答案:

答案 0 :(得分:41)

这是因为您尝试从bar类而不是FooBar实例访问FooBarFooBar类没有与之关联的任何bar对象 - bar只是一个sqlalchemy InstrumentedAttribute 。这就是你得到错误的原因:

AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with FooBar.bar has an attribute 'foo'

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

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

ses.query(FooBar).join(Bar).join(Foo).filter(Foo.name == "blah")

答案 1 :(得分:26)

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

ses.query(FooBar).join(Foobar.bar).join(Bar.foo).filter(Foo.name == "blah")

答案 2 :(得分:0)

错误地配置SQLAlchemy关系可能导致的相关错误:

AttributeError: Neither 'Column' object nor 'Comparator' object has an attribute 'corresponding_column'

就我而言,我错误地定义了这样的关系:

namespace   = relationship(PgNamespace, id_namespace, backref="classes")

id_namespace的{​​{1}}参数应该根本就不存在。 SQLAlchemy试图将其解释为不同类型的参数,并且失败并出现难以理解的错误。

答案 3 :(得分:0)

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

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