13 Stimmen

SQLAlchemy erwartet ein Objekt, findet aber eine Tabelle

Ich beginne derzeit mit Sqlalchemy. In meinem aktuellen Projekt muss ich einen Teil mit Flask und einen anderen Teil über die Kommandozeile erledigen. Der Teil über Flask läuft gut, Schnittstelle mit Sqlalchemy und alle, aber die Kommandozeile Teil ist nicht.

Der Fehler, den ich erhalte, lautet

ArgumentError("Class object expected, got 'Table('documentos', 
 MetaData(bind=Engine(postgresql://user:password@localhost/clasificador)), 
 Column('id', Integer(), table=<documentos>, primary_key=True, nullable=False),
 Column('nombre', String(length=248), table=<documentos>), schema=None)'.",)

Ich habe mein Glück mit Google und Lesen deklarative Sqlalchemy versucht, aber ich kann nicht finden, was das Problem sein könnte. Der Code im Modul ist:

from sqlalchemy.orm import sessionmaker
from db import engine,Base
#some other code
session = sessionmaker(bind=engine)
doc = modelos.documento.Documento(os.path.basename(nelto))
session.add(doc) #here fails
session.remove()

db ist das Modul, in dem ich den gemeinsamen Code für Sqlalchemy habe. Das meiste davon stammt aus der Flask-Dokumentation, und db_session wird nur für Flask verwendet, ich habe eine andere Sitzung für das andere Modul.

from sqlalchemy import create_engine
from sqlalchemy.orm import scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

sqldebug=True 

engine = create_engine( 
    'postgresql://user:passwd@localhost/clasificador',
    convert_unicode=True,
    echo=sqldebug)
db_session = scoped_session(sessionmaker(autocommit=False,
                                     autoflush=False,
                                     bind=engine))
Base = declarative_base(bind=engine)
Base.query = db_session.query_property()

Zum Schluss noch das Modul "documento", obwohl ich bezweifle, dass das Problem hier liegt. from sqlalchemy import Spalte, Ganzzahl, String von db importieren Base

class Documento(Base):
    '''Clase definiendo los documentos'''
    __tablename__ = "documentos"

    id = Column(Integer,primary_key=True) 
    nombre = Column(String(248))

    def __init__(self,nombre):
        self.nombre = nombre             

    def __repr__(self):
        return '<Documento %r>' % self.nombre

Einige der Kommentare/Namen sind auf Spanisch, aber ich denke, man kann sie getrost ignorieren, wenn es nötig ist, werde ich die Übersetzungen machen

In Anlehnung an den Code von Lafada habe ich eine weitere Datei mit just erstellt:

from sqlalchemy.orm import sessionmaker
from modelos.documento import Documento
from db import Base, engine
import os

Session = sessionmaker(bind=engine)
session = Session()
doc = Documento(os.path.basename('/tmp/test.py')) #here fails
session.add(doc) 
session.commit()

und es läuft einwandfrei. Der einzige Unterschied, den ich erkennen kann, ist, wie die Sitzung erstellt wird, ich habe geändert, dass auch in meinem ursprünglichen Code, aber es hält immer den gleichen Fehler.

Ich fand den Übeltäter, es war nicht auf den Code, den ich zeige, aber in einer anderen Klasse, die versuchte, eine Beziehung mit ihm zu erstellen, aber die Verknüpfung mit der Tabelle anstelle des Objekts. Bis ich verschiedene andere Dinge ausprobiert habe, konnte ich es nicht auf das eigentliche Problem zurückführen

29voto

Brandon Rhodes Punkte 75647

Ich habe diesen Fehler schon einmal gesehen, wenn ich das vergesse ForeignKey() nimmt den Namen einer Datenbanktabelle und eines Feldes, aber das relationship() nimmt stattdessen den Namen einer ORM-Klasse. Das heißt, ich schreibe manchmal:

movie_id = Column(Integer, ForeignKey('movie.id'))
movie = relationship('movie')  # WRONG!
# Exception: "SQLAlchemy expects to find an object…"

Was ich stattdessen schreiben sollte, wenn ich davon ausgehe, dass movie der Name der Datenbanktabelle ist (nicht dass SQL auf die Großschreibung von Tabellennamen achtet!) und dass Movie ist der Name meiner Python ORM-Klasse, ist:

movie_id = Column(Integer, ForeignKey('movie.id'))
movie = relationship('Movie')  # Works!

6voto

Nilesh Punkte 19313

Ich habe Ihren Code auf Mysql ausprobiert (ich habe postgress nicht auf meinem PC :(). Ich setze den Code hier bitte überprüfen, weil das funktioniert gut für mich.

#filename: /tmp/test.py
from sqlalchemy import create_engine, Column, Integer, String
from sqlalchemy.orm import scoped_session, sessio

nmaker
from sqlalchemy.ext.declarative import declarative_base
import os

sqldebug=True 

engine = create_engine('mysql://test:test@localhost/test1', 
            convert_unicode=True,
            echo=sqldebug)

#create_engine( 
#           'postgresql://user:passwd@localhost/clasificador',
#           convert_unicode=True,
#           echo=sqldebug)

db_session = scoped_session(sessionmaker(autocommit=False,
                                         autoflush=False,
                                         bind=engine))
Base = declarative_base(bind=engine)
Base.query = db_session.query_property()

class Documento(Base):
    '''Clase definiendo los documentos'''
    __tablename__ = "documentos"

    id = Column(Integer,primary_key=True)
    nombre = Column(String(248))

    def __init__(self,nombre):         
        self.nombre = nombre

    def __repr__(self):
        return '<Documento %r>' % self.nombre

Base.metadata.create_all(engine)

from sqlalchemy.orm import sessionmaker
#some other code
Session = sessionmaker(bind=engine)
session = Session()
doc = Documento(os.path.basename('/tmp/test.py'))
session.add(doc) #here fails
session.commit()

Ausgabe-Protokoll

In [11]: ed /tmp/test.py
Editing... done. Executing edited code...
2011-11-18 08:48:41,254 INFO sqlalchemy.engine.base.Engine SELECT DATABASE()
2011-11-18 08:48:41,254 INFO sqlalchemy.engine.base.Engine ()
2011-11-18 08:48:41,259 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'character_set%%'
2011-11-18 08:48:41,259 INFO sqlalchemy.engine.base.Engine ()
2011-11-18 08:48:41,290 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'lower_case_table_names'
2011-11-18 08:48:41,290 INFO sqlalchemy.engine.base.Engine ()
2011-11-18 08:48:41,320 INFO sqlalchemy.engine.base.Engine SHOW COLLATION
2011-11-18 08:48:41,320 INFO sqlalchemy.engine.base.Engine ()
2011-11-18 08:48:41,339 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'sql_mode'
2011-11-18 08:48:41,339 INFO sqlalchemy.engine.base.Engine ()
2011-11-18 08:48:41,343 INFO sqlalchemy.engine.base.Engine DESCRIBE `documentos`
2011-11-18 08:48:41,343 INFO sqlalchemy.engine.base.Engine ()
2011-11-18 08:48:41,389 INFO sqlalchemy.engine.base.Engine ROLLBACK
2011-11-18 08:48:41,391 INFO sqlalchemy.engine.base.Engine 
CREATE TABLE documentos (
    id INTEGER NOT NULL AUTO_INCREMENT, 
    nombre VARCHAR(248), 
    PRIMARY KEY (id)
)

2011-11-18 08:48:41,391 INFO sqlalchemy.engine.base.Engine ()
2011-11-18 08:48:41,683 INFO sqlalchemy.engine.base.Engine COMMIT
2011-11-18 08:48:41,698 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2011-11-18 08:48:41,700 INFO sqlalchemy.engine.base.Engine INSERT INTO documentos (nombre) VALUES (%s)
2011-11-18 08:48:41,700 INFO sqlalchemy.engine.base.Engine ('test.py',)
2011-11-18 08:48:41,701 INFO sqlalchemy.engine.base.Engine COMMIT

Laut Protokoll wird dieser Code einen neuen Datensatz in der Datenbank hinzufügen. Wenn Sie eine andere Abfrage haben, dann ist es gut, wenn ich Ihnen dabei helfen kann :)

0voto

dario Punkte 190

Ich bin nicht so vertraut mit Sqlalchemy und sein deklaratives Format, aber eine Sache, die ich denke, ist nicht korrekt ist Sie überschreiben die init Methode, ohne die übergeordnete Klasse aufzurufen (hier ist es Base ).

Entfernen Sie die init oder rufen Sie an Base.init(self) .

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X