Подтвердить что ты не робот

AttributeError при запросе: ни объект InstrumentedAttribute, ни 'Comparator' не имеют атрибута

Следующий код:

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'

Любые объяснения, почему это происходит, и руководство к тому, как можно достичь такого?

4b9b3361

Ответ 1

Это происходит потому, что вы пытаетесь получить доступ к bar из класса FooBar, а не экземпляра FooBar. Класс FooBar не имеет связанных с ним объектов bar - bar - это всего лишь sqlalchemy InstrumentedAttribute. Вот почему вы получаете сообщение об ошибке:

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

Вы получите ту же ошибку, набрав FooBar.bar.foo.name вне запроса sqlalchemy.

Решение состоит в том, чтобы вызвать класс Foo непосредственно:

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

Ответ 2

Я не могу технически объяснить, что происходит, но вы можете обойти эту проблему, используя:

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

Ответ 3

Связанная ошибка, которая может быть вызвана неправильной настройкой отношений SQLAlchemy:

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

В моем случае я неправильно определил такое отношение:

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

Аргумент id_namespace для relationship() должен просто отсутствовать. SQLAlchemy пытается интерпретировать его как аргумент другого типа и не удается с непостижимой ошибкой.