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

SQLAlchemy ожидает объект, но находит таблицу

Сейчас я начинаю с sqlalchemy. В моем текущем проекте мне нужно сделать часть с Flask и другой частью из командной строки. Часть о колбе работает нормально, взаимодействует с sqlalchemy и все, но часть командной строки не является.

Ошибка, которую я получаю,

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

Я пробовал свою удачу с Google и читаю декларативную sqlalchemy, но я не могу найти, что может быть проблемой. Код в модуле:

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 - это модуль, в котором у меня есть общий код для sqlalchemy. большая часть из них поступает из документации флагов, а db_session используется только для фляжки, я сделал другой сеанс для другого модуля.

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:[email protected]/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()

Наконец, вот модуль "documento", хотя я сомневаюсь, что проблема здесь. из sqlalchemy import Column, Integer, String from db import 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

Некоторые комментарии/имена на испанском языке, но я думаю, что вы можете смело игнорировать их, если это необходимо, я сделаю переводы

Следуя коду Lafada, я создал еще один файл:

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

и он работает просто отлично. Единственное различие, которое я могу заметить, это то, как создается сеанс, я также изменил это в своем исходном коде, но он продолжает получать ту же ошибку.

Я нашел виновника, это не было в коде, который я показываю, но в другом классе, который пытался создать с ним отношения, но ссылался на таблицу вместо объекта. Пока я не попробовал несколько других вещей, я не мог отследить его до реальной проблемы.

4b9b3361

Ответ 1

Я пробовал свой код на mysql (у меня нет постгрессии в моем компьютере:(). Я помещаю этот код здесь, пожалуйста, проверьте это, потому что это работает отлично для меня.

#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:[email protected]/test1', 
            convert_unicode=True,
            echo=sqldebug)

#create_engine( 
#           'postgresql://user:[email protected]/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()

Журнал вывода

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

В соответствии с журналом этот код добавит одну новую запись в db. Если у вас есть другой запрос, тогда это хорошо, если я вам помогу:)

Ответ 2

Я видел эту ошибку раньше, если забываю, что ForeignKey() берет имя таблицы и поля базы данных, но вместо этого relationship() вместо имени класса ORM. То есть, я иногда пишу:

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

Вместо этого я должен писать, считая, что movie - это имя таблицы базы данных (а не то, что SQL обращает внимание на капитализацию имени таблицы!) и что movie - это имя моего класса ORM класса Python:

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

Ответ 3

Я не так хорошо знаком с sqlalchemy и его декларативным форматом, но одна вещь, которая, я думаю, неверна, - это переписывание метода init без вызова его родительского класса (здесь это Base).

Удалите init или вызовите Base.init(self).