SQLAlchemy需要一个对象,但找到一个Table

Wil*_*rog 12 python sqlalchemy

我现在开始使用sqlalchemy.在我目前的项目中,我必须使用Flask和命令行中的其他部分做一些工作.关于烧瓶的部分运行正常,与sqlalchemy和所有的接口,但命令行部分不是.

我得到的错误是

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)'.",)
Run Code Online (Sandbox Code Playgroud)

我试过我的运气与谷歌和阅读声明性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()
Run Code Online (Sandbox Code Playgroud)

db是我有sqlalchemy公共代码的模块.其中大部分来自于flask文档,而db_session仅用于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()
Run Code Online (Sandbox Code Playgroud)

最后,这里是"documento"模块,虽然我怀疑问题在这里.来自sqlalchemy导入列,整数,来自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
Run Code Online (Sandbox Code Playgroud)

一些评论/名称是西班牙语,但我认为你可以放心地忽略它们,如果有必要我会做翻译

按照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()
Run Code Online (Sandbox Code Playgroud)

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

我找到了罪魁祸首,它不是我正在展示的代码,而是在一个不同的类中,它尝试与它建立关系但链接到表而不是对象.直到我尝试了其他几件事,我无法追溯到真正的问题

Bra*_*des 28

我之前看到过这个错误,如果我忘记了它ForeignKey()取一个数据库表和字段relationship()的名称,但它取而代之的是ORM类的名称.也就是说,我有时写道:

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

我应该写什么,假设这movie是数据库表的名称(不是SQL注意表名大小写!),这Movie是我的Python ORM类的名称,是:

movie_id = Column(Integer, ForeignKey('movie.id'))
movie = relationship('Movie')  # Works!
Run Code Online (Sandbox Code Playgroud)

  • 哇,十亿就是这个.我做了那件事.这种不一致有点可怕. (4认同)
  • 有人可能会认为sqlalchemy可以为这种错误发出更好的错误信息.事实上,今天被我咬了,我会发布一个错误报告. (2认同)

Nil*_*esh 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: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()
Run Code Online (Sandbox Code Playgroud)

输出日志

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
Run Code Online (Sandbox Code Playgroud)

根据日志,此代码将在db中添加一条新记录.如果您有任何其他查询,那么如果我在那帮助你,它会很好:)

  • 我终于重写了所有代码并且它有效,它在不同的文件中几乎相同.所以我奖励你的回复,因为我从来没有试过把它写在另一个文件中(并且不应该是一个解决方案) (2认同)