当我运行initializedb.py
脚本时,我的表创建正常但是当我尝试插入任何数据时,我收到以下错误:
TypeError: unbound method after_attach() must be called with ZopeTransactionExtension instance as first argument (got Session instance instead)
为什么我收到此错误?我试过谷歌搜索错误,但我找到的唯一与我有关的例子与不正确的查询有关。
我的包结构和代码的相关部分如下:
在我的Pyramid应用程序中,我没有定义models.py
文件中的所有模型,而是创建了一个名为models的独立包,并将所有模型类放在那里。
基本上,我有
myapp/
models/
__init__.py
meta.py
school.py
__init__.py
我的主__init__.py
有:
from myapp.models.meta import (
DBSession,
Base,
)
同样,__init__.py
中的models
文件包含:
from .meta import DBSession
from .school import School
meta.py
内的 models
有:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import (
scoped_session,
sessionmaker,
)
from zope.sqlalchemy import ZopeTransactionExtension
Base = declarative_base()
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension))
模型文件school.py
具有:
from .meta import (
Base,
get_prefix,
)
class School(Base):
""" The SQLAlchemy declarative model class for a School object. """
__tablename__ = 'schools'
id = Column(Integer, primary_key=True)
school_code = Column(String(10))
最后,scripts/initializedb.py
文件有:
from myapp.models.meta import (
Base,
DBSession,
)
from myapp.models import (
School,
)
def main(argv=sys.argv):
if len(argv) < 2:
usage(argv)
config_uri = argv[1]
options = parse_vars(argv[2:])
setup_logging(config_uri)
settings = get_appsettings(config_uri, options=options)
engine = engine_from_config(settings, 'sqlalchemy.')
DBSession.configure(bind=engine)
Base.metadata.create_all(engine)
with transaction.manager:
demo_school = School(school_code="SC-123")
DBSession.add(demo_school)
修改
完整的追溯如下:
2014-06-22 20:18:31,577 INFO [sqlalchemy.engine.base.Engine][MainThread] SHOW VARIABLES LIKE 'sql_mode'
2014-06-22 20:18:31,577 INFO [sqlalchemy.engine.base.Engine][MainThread] ()
2014-06-22 20:18:31,585 DEBUG [sqlalchemy.engine.base.Engine][MainThread] Col ('Variable_name', 'Value')
2014-06-22 20:18:31,586 DEBUG [sqlalchemy.engine.base.Engine][MainThread] Row ('sql_mode', '')
2014-06-22 20:18:31,586 INFO [sqlalchemy.engine.base.Engine][MainThread] SELECT DATABASE()
2014-06-22 20:18:31,586 INFO [sqlalchemy.engine.base.Engine][MainThread] ()
2014-06-22 20:18:31,587 DEBUG [sqlalchemy.engine.base.Engine][MainThread] Col ('DATABASE()',)
2014-06-22 20:18:31,587 DEBUG [sqlalchemy.engine.base.Engine][MainThread] Row ('myapp',)
2014-06-22 20:18:31,588 INFO [sqlalchemy.engine.base.Engine][MainThread] show collation where `Charset` = 'utf8' and `Collation` = 'utf8_bin'
2014-06-22 20:18:31,588 INFO [sqlalchemy.engine.base.Engine][MainThread] ()
2014-06-22 20:18:31,590 DEBUG [sqlalchemy.engine.base.Engine][MainThread] Col ('Collation', 'Charset', 'Id', 'Default', 'Compiled', 'Sortlen')
2014-06-22 20:18:31,591 DEBUG [sqlalchemy.engine.base.Engine][MainThread] Row ('utf8_bin', 'utf8', 83L, '', 'Yes', 1L)
2014-06-22 20:18:31,592 INFO [sqlalchemy.engine.base.Engine][MainThread] SELECT CAST('test plain returns' AS CHAR(60)) AS anon_1
2014-06-22 20:18:31,592 INFO [sqlalchemy.engine.base.Engine][MainThread] ()
2014-06-22 20:18:31,593 INFO [sqlalchemy.engine.base.Engine][MainThread] SELECT CAST('test unicode returns' AS CHAR(60)) AS anon_1
2014-06-22 20:18:31,593 INFO [sqlalchemy.engine.base.Engine][MainThread] ()
2014-06-22 20:18:31,594 INFO [sqlalchemy.engine.base.Engine][MainThread] SELECT CAST('test collated returns' AS CHAR CHARACTER SET utf8) COLLATE utf8_bin AS anon_1
2014-06-22 20:18:31,595 INFO [sqlalchemy.engine.base.Engine][MainThread] ()
2014-06-22 20:18:31,596 INFO [sqlalchemy.engine.base.Engine][MainThread] DESCRIBE `a3fhs32g_schools`
2014-06-22 20:18:31,597 INFO [sqlalchemy.engine.base.Engine][MainThread] ()
2014-06-22 20:18:31,598 DEBUG [sqlalchemy.engine.base.Engine][MainThread] Col ('Field', 'Type', 'Null', 'Key', 'Default', 'Extra')
2014-06-22 20:18:31,598 DEBUG [sqlalchemy.engine.base.Engine][MainThread] Row ('id', 'int(11)', 'NO', 'PRI', None, 'auto_increment')
2014-06-22 20:18:31,598 INFO [sqlalchemy.engine.base.Engine][MainThread] DESCRIBE `a3fhs32g_students`
2014-06-22 20:18:31,598 INFO [sqlalchemy.engine.base.Engine][MainThread] ()
2014-06-22 20:18:31,599 DEBUG [sqlalchemy.engine.base.Engine][MainThread] Col ('Field', 'Type', 'Null', 'Key', 'Default', 'Extra')
2014-06-22 20:18:31,599 DEBUG [sqlalchemy.engine.base.Engine][MainThread] Row ('id', 'int(11)', 'NO', 'PRI', None, 'auto_increment')
Traceback (most recent call last):
File "../bin/initialize_myapp_db", line 9, in <module>
load_entry_point('myapp==0.0', 'console_scripts', 'initialize_myapp_db')()
File "/var/www/html/myapp/app/myapp/myapp/myapp/scripts/initializedb.py", line 44, in main
DBSession.add(model)
File "/var/www/html/myapp/app/myapp/local/lib/python2.7/site-packages/SQLAlchemy-0.9.4-py2.7-linux-i686.egg/sqlalchemy/orm/scoping.py", line 149, in do
return getattr(self.registry(), name)(*args, **kwargs)
File "/var/www/html/myapp/app/myapp/local/lib/python2.7/site-packages/SQLAlchemy-0.9.4-py2.7-linux-i686.egg/sqlalchemy/orm/session.py", line 1478, in add
self._save_or_update_state(state)
File "/var/www/html/myapp/app/myapp/local/lib/python2.7/site-packages/SQLAlchemy-0.9.4-py2.7-linux-i686.egg/sqlalchemy/orm/session.py", line 1490, in _save_or_update_state
self._save_or_update_impl(state)
File "/var/www/html/myapp/app/myapp/local/lib/python2.7/site-packages/SQLAlchemy-0.9.4-py2.7-linux-i686.egg/sqlalchemy/orm/session.py", line 1744, in _save_or_update_impl
self._save_impl(state)
File "/var/www/html/myapp/app/myapp/local/lib/python2.7/site-packages/SQLAlchemy-0.9.4-py2.7-linux-i686.egg/sqlalchemy/orm/session.py", line 1716, in _save_impl
self._attach(state)
File "/var/www/html/myapp/app/myapp/local/lib/python2.7/site-packages/SQLAlchemy-0.9.4-py2.7-linux-i686.egg/sqlalchemy/orm/session.py", line 1844, in _attach
self.dispatch.after_attach(self, state.obj())
File "/var/www/html/myapp/app/myapp/local/lib/python2.7/site-packages/SQLAlchemy-0.9.4-py2.7-linux-i686.egg/sqlalchemy/event/attr.py", line 257, in __call__
fn(*args, **kw)
TypeError: unbound method after_attach() must be called with ZopeTransactionExtension instance as first argument (got Session instance instead)
答案 0 :(得分:1)
DBSession
是scoped_session对象。要获得实际会话,您必须调用它(它会触发对底层会话工厂的调用)。
def main(argv=sys.argv):
...
DBSession.configure(bind=engine)
Base.metadata.create_all(engine)
session = DBSession()
....
session.add(model)
答案 1 :(得分:0)
错误意味着你需要一个DBSession的实例,但是这个类。我真的不知道金字塔,但是DBSession configure
调用可能会返回一个实例?如果是这样,您应该捕获返回值并在其上调用add
。