it-swarm.com.de

AttributeError beim Abfragen: Weder 'InstrumentedAttribute'-Objekt noch' Comparator 'haben ein Attribut

Der folgende Code:

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

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

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

    foo = relationship("Foo")


class FooBar(Base):
    __table= "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")

gibt mir diesen Fehler:

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

Irgendwelche Erklärungen, warum dies geschieht, und Anleitungen, wie dies erreicht werden kann?

30

Dies liegt daran, dass Sie versuchen, auf bar von der FooBar-Klasse anstatt von einer FooBar-Instanz zuzugreifen. Der FooBar-Klasse sind keine bar-Objekte zugeordnet - bar ist nur eine sqlalchemy InstrumentedAttribute . Deshalb erhalten Sie den Fehler:

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

Sie erhalten dieselbe Fehlermeldung, wenn Sie FooBar.bar.foo.name außerhalb der sqlalchemy-Abfrage eingeben.

Die Lösung ist, die Foo-Klasse direkt aufzurufen:

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

Ich kann nicht technisch erklären, was passiert, aber Sie können dieses Problem umgehen, indem Sie Folgendes verwenden:

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

Ich habe dieselbe Fehlermeldung Neither 'InstrumentedAttribute' object nor 'Comparator' has an attribute erhalten, aber in meinem Fall bestand das Problem darin, dass mein Modell eine Spalte namens query enthielt, die die interne Eigenschaft model.query überschrieb.

Ich entschied mich, diese Spalte in query_text umzubenennen, und der Fehler wurde entfernt. Alternativ hätte das Übergeben des name=-Arguments an die Column-Methode funktioniert: query = db.Column(db.TEXT, name='query_text').

0
tokenizer_fsj

Ein verwandter Fehler, der durch falsche Konfiguration Ihrer SQLAlchemy-Beziehungen verursacht werden kann:

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

In meinem Fall habe ich eine solche Beziehung falsch definiert:

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

Das id_namespace-Argument für relationship() sollte überhaupt nicht vorhanden sein. SQLAlchemy versucht, es als Argument eines anderen Typs zu interpretieren und schlägt mit einem undurchschaubaren Fehler fehl.

0
qris