金字塔:DBSession.add(model)返回Type Error

时间:2014-06-21 17:25:11

标签: python sqlalchemy pyramid

当我运行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)

2 个答案:

答案 0 :(得分:1)

在您的情况下,

DBSessionscoped_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