查询时出现属性错误:“InstrumentedAttribute”对象和“Comparator”都没有属性

问题描述 投票:0回答:7

以下代码:

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'

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

python sqlalchemy attributeerror
7个回答
114
投票

这是因为您尝试从

bar
类而不是
FooBar
实例访问
FooBar
FooBar
类没有任何与之关联的
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")

40
投票

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

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

7
投票

我遇到了同样的错误

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

我决定将该列重命名为

query_text
,从而消除了错误。或者,将
name=
参数传递给 Column 方法也可以:
query = db.Column(db.TEXT, name='query_text')


2
投票

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

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

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

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

id_namespace
relationship()
参数根本不应该存在。 SQLAlchemy 试图将其解释为不同类型的参数,但失败并出现难以理解的错误。


1
投票
stmt = (
   select(Bar.id).
   where(Bar.foo.has(Foo.name=="test"))
)

也许它会有用...我在这里找到它:https://docs.sqlalchemy.org/en/14/tutorial/orm_lated_objects.html#exists-forms-has-any


1
投票

这是一个简单的工作示例,与同一个表有多个关系。这通常可以避免出现错误

AttributeError while querying: Neither 'InstrumentedAttribute' object nor 'Comparator' has an attribute

def get_company(db: Session, company_id: int):
    best_contact = aliased(User, name="best_contact ")
    other_contact = aliased(User, name="other_contact")
    
    row = (
        db.query(Company, best_contact, other_contact)
        .join(best_contact, Company.best_contact_id == best_contact.id)
        .join(other_contact, Company.other_contact_id == other_contact.id)
        .filter(Company.id == company_id)
        .first()
    )
    return row

    

0
投票

如果我的模型 (FooBar) 中有 @hyrbrid_property 会怎样,例如:

@hybrid_property
def foo_name(self):
   return self.bar.foo.name + " xyz"

这种情况下,如何查询混合属性?

© www.soinside.com 2019 - 2024. All rights reserved.