我目前正在使用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)'.",)
我已经尝试过谷歌和阅读声明性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公共代码的模块。其中大部分来自于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()
最后,这是“documento”模块,虽然我怀疑问题在这里。 来自sqlalchemy import Column,Integer,String 来自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()
它运行得很好。我能发现的唯一区别是会话是如何创建的,我在原始代码中也修改了它,但它仍然会出现同样的错误。
我找到了罪魁祸首,它不在我正在展示的代码上,而是在另一个类中试图与它建立关系但是链接到表而不是对象。直到我尝试了其他一些事情,我无法将其追溯到真正的问题
答案 0 :(得分: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!
答案 1 :(得分: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()
输出日志
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 :(得分:0)
我对sqlalchemy及其声明性格式不是很熟悉,但我认为不正确的一件事是你在不调用其父类的情况下覆盖init
方法(这里是Base
)
删除init
或致电Base.init(self)
。