2011-11-17 27 views
12

我目前正在从sqlalchemy开始。在我目前的项目中,我必须在Flask和命令行的其他部分做一些工作。关于烧瓶的部分运行良好,与sqlalchemy和所有接口,但命令行部分不是。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)'.",) 

我已经尽我的运气与谷歌和阅读声明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的进口列,整数,从数据库导入基本字符串

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

,它运行得很好。我能发现的唯一区别是会话是如何创建的,我已经在我的原始代码中修改了它,但它始终得到相同的错误。

我发现的罪魁祸首,它不是在我显示的代码上,而是在一个不同的类中试图创建与它的关系,但链接到表而不是对象。直到我尝试了其他几件事情,我无法追查它到真正的问题

回答

6

我想在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:[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 

由于每个日志,该代码将在数据库中添加一个新的记录。如果您有任何其他查询,则它的好,如果我是你的一个:)

+0

这很奇怪,我已经运行你的代码(改变它为postgres),它运行良好,我已经重新安排它只是以下,它仍然运行(通过进口到其他部分代码) Session = sessionmaker(bind = engine) session = Session() doc = Documento(os.path.basename('/ tmp/test.py')) session.add(doc)#这里失败 session.commit() – Willyfrog

+0

我修改了原来的问题来添加新代码,因为在这里看不到它 – Willyfrog

+2

我终于重写了所有的代码,它的工作原理在不同的文件中几乎是一样的。 所以我给你答复,因为我从来没有试图写在另一个文件(并不应该是一个解决方案) – Willyfrog

0

我不熟悉sqlalchemy及其声明格式,但我认为不正确的一件事是你覆盖init方法,而不会调用其父母的班级(这里是Base)。

删除init或致电Base.init(self)

+0

对于那部分,我也跟着从[瓶]教程(http://flask.pocoo.org/docs/patterns/sqlalchemy/)和它的作品,当我使用烧瓶,没有抱怨。 无论如何感谢:) – Willyfrog

+0

好吧,但请记住,Flask可能会添加一些东西,以便让您定义该init方法。在纯python + sqlalchemy中可能不起作用! – dario

+0

在任何其他情况下,我会说你很可能是正确的,但即使sqlalchemy教程这样做,所以我有信心,这不是问题。感谢您指出它:) – Willyfrog

28

我已经看到了错误,如果之前我忘了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! 
+4

哇,+十亿这个。我做了那件事。这种不一致有点可怕。 – andronikus

+0

的确,谢谢! – AME

+2

有人可能会认为sqlalchemy可以为这种错误发出更好的错误消息。事实上,今天我被这个问题困扰了,我会发布一个错误报告。 –

相关问题