2013-05-16 13 views
24

den folgenden Code:Attribute beim Abfragen: Weder ‚InstrumentedAttribute‘ Objekt noch ‚Vergleicher‘ hat ein Attribut

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") 

gibt mir diese Fehlermeldung:

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

Irgendwelche Erklärungen, warum dies geschieht, und Anleitung, wie so etwas erreicht werden könnte?

Antwort

31

Dies liegt daran, dass Sie versuchen, den Zugriff auf bar von der FooBar Klasse statt einer FooBar Instanz. Die FooBar Klasse hat keine bar Objekte, die damit verbunden sind - bar ist nur ein sqlalchemy InstrumentedAttribute. Dies ist, warum Sie den Fehler:

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

Sie werden die gleichen Fehler von FooBar.bar.foo.name außerhalb der sqlalchemy Abfrage eingeben.

Die Lösung ist die Foo Klasse direkt zu nennen:

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

Was ist, wenn die Tabelle mehrere Beziehungen zu 'Foo' hat ? –

19

Ich kann technisch nicht erklären, was passiert, aber man kann durch die Verwendung, um dieses Problem zu umgehen:

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

Sie können verstehen, warum es in der Dokumentation funktioniert: http://docs.sqlalchemy.org/en/rel_0_9/orm/tutorial.html#querying-with-joins –

0

einem verwandten Fehler, die Ihre SQLAlchemy Beziehungen verursacht werden können falsch durch die Konfiguration:

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

In meinem Fall habe ich falsch definiert ein Beziehung wie diese:

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

Die id_namespace Argument zu relationship() sollte einfach nicht da sein. SQLAlchemy versucht, es als ein Argument eines anderen Typs zu interpretieren und mit einem unerklärlichen Fehler zu versagen.