Python SQLAlchemy需要一个对象,但找到一个表

Python SQLAlchemy需要一个对象,但找到一个表,python,sqlalchemy,Python,Sqlalchemy,我现在开始学习sqlalchemy。在我当前的项目中,我必须使用Flask做一些工作,从命令行做一些其他工作。关于flask的部分运行良好,与sqlalchemy和all接口,但命令行部分不是 我得到的错误是 ArgumentError("Class object expected, got 'Table('documentos', MetaData(bind=Engine(postgresql://user:password@localhost/clasificador)), Colu

我现在开始学习sqlalchemy。在我当前的项目中,我必须使用Flask做一些工作,从命令行做一些其他工作。关于flask的部分运行良好,与sqlalchemy和all接口,但命令行部分不是

我得到的错误是

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)'.",)
db是我拥有sqlalchemy通用代码的模块。大部分来自flask文档,db_会话仅用于flask,我为另一个模块创建了一个不同的会话

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()
最后,这里是“documento”模块,尽管我怀疑问题在这里。 从sqlalchemy导入列,整数,字符串 从数据库导入库

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
它运行得很好。我能发现的唯一区别是会话是如何创建的,我在我的原始代码中也对其进行了修改,但它总是得到相同的错误


我发现了罪魁祸首,它不在我展示的代码中,而是在另一个类中,该类试图与它创建关系,但链接到表而不是对象。在我尝试了其他一些方法之前,我无法将其追溯到真正的问题

我对sqlalchemy及其声明格式不太熟悉,但有一点我认为是不正确的,那就是在不调用其父类的情况下覆盖
init
方法(这里是
Base


删除
init
或调用
Base.init(self)

我在mysql上尝试了你的代码(我的电脑中没有postgress:()。我把代码放在这里,请检查一下,因为这对我来说很好

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

根据日志,此代码将在db中添加一条新记录。如果您有任何其他查询,那么如果我在这方面帮助您,那就好了:)

如果我忘记了
ForeignKey()
采用数据库表和字段的名称,而
relationship()
采用ORM类的名称,那么我以前就看到过这个错误。也就是说,我有时会写:

movie_id = Column(Integer, ForeignKey('movie.id'))
movie = relationship('movie')  # WRONG!
# Exception: "SQLAlchemy expects to find an object…"
我应该写的是,假设
movie
是数据库表的名称(SQL并不注意表名的大小写!),而
movie
是我的Python ORM类的名称,则是:

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

对于这一部分,我遵循了的教程,当我使用flask时,它可以正常工作,没有任何抱怨。无论如何,谢谢:)好的,但请记住,Flask可能会添加一些东西,以便让您定义init方法。在纯python+sqlalchemy中,这可能不起作用!在任何其他情况下,我都会说您很可能是正确的,但即使是sqlalchemy教程也是这样做的,所以我相信这不是问题所在。无论如何,感谢您指出:)这很奇怪,我已经运行了您的代码(将其更改为postgres)并且运行良好,我已经将其重新安排为以下内容,并且它仍然运行(导入到我的代码的其他部分)Session=sessionmaker(bind=engine)Session=Session()doc=Documento(os.path.basename('/tmp/test.py'))session.add(doc)#此处失败session.commit()我修改了原始问题以添加新代码,因为在此处无法正确查看。我最终重写了所有代码,代码正常工作,在不同的文件中几乎相同。所以我奖励你这个回复,因为我从来没有尝试过将它写在另一个文件中(也不应该是一个解决方案)哇,这是10亿美元。我就是这么做的。这种不一致性有点可怕。有人可能会认为sqlalchemy可以为这种错误发出更好的错误消息。事实上,今天我已经被这个问题困扰了,我将发布一个bug报告。两周前我遇到了这个问题,忘记了它,然后刚刚遇到了它。让我感觉像是旁白鲍勃踩在耙子上。
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
movie_id = Column(Integer, ForeignKey('movie.id'))
movie = relationship('movie')  # WRONG!
# Exception: "SQLAlchemy expects to find an object…"
movie_id = Column(Integer, ForeignKey('movie.id'))
movie = relationship('Movie')  # Works!