SQLAlchemy initialize_db.py - 初始数据填充语法有问题

时间:2014-07-29 19:11:25

标签: python sqlalchemy pyramid

我有以下表格:

 Schema |      Name      | Type  |  Owner
--------+----------------+-------+---------
 public | fds_funds      | table | finance
 public | fdt_fund_types | table | finance
 public | usf_user_funds | table | finance
 public | usr_users      | table | finance

我试图在几个数据库中初始化一些数据。基本上我试图添加一个"现金" fund_type,然后使用该fund_type添加基金。当然,问题是我不知道fund_type的ID,直到它在数据库中,并且我不想对其进行硬编码。

所以我的initializedb.py目前看起来像这样:

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:
        fund_type = FundType(fdt_type_name='cash')
        DBSession.add(fund_type)
        transaction.commit()

    with transaction.manager:
        fund = Fund(fds_name='Vanguard Prime Money Market Fund', fds_symbol='vmmxx', fds_fdt_fund_type_id=fund_type.fdt_fund_type_id)
        DBSession.add(fund)
        transaction.commit()

因此,当我运行初始化脚本时,我得到以下输出:

2014-07-29 19:05:09,011 INFO  [sqlalchemy.engine.base.Engine][MainThread] {}
2014-07-29 19:05:09,014 INFO  [sqlalchemy.engine.base.Engine][MainThread] COMMIT
2014-07-29 19:05:09,022 INFO  [sqlalchemy.engine.base.Engine][MainThread] BEGIN (implicit)
2014-07-29 19:05:09,024 INFO  [sqlalchemy.engine.base.Engine][MainThread] INSERT INTO fdt_fund_types (fdt_type_name, fdt_usr_user_id) VALUES (%(fdt_type_name)s, %(fdt_usr_user_id)s) RETURNING fdt_fund_types.fdt_fund_type_id
2014-07-29 19:05:09,024 INFO  [sqlalchemy.engine.base.Engine][MainThread] {'fdt_type_name': 'cash', 'fdt_usr_user_id': None}
2014-07-29 19:05:09,025 INFO  [sqlalchemy.engine.base.Engine][MainThread] COMMIT
Traceback (most recent call last):
  File "/var/www/finance/finance-env/bin/initialize_corefinance_db", line 9, in <module>
    load_entry_point('corefinance==0.0', 'console_scripts', 'initialize_corefinance_db')()
  File "/var/www/finance/corefinance/corefinance/scripts/initializedb.py", line 45, in main
    fund = Fund(fds_name='Vanguard Prime Money Market Fund', fds_symbol='vmmxx', fds_fdt_fund_type_id=fund_type.fdt_fund_type_id)
  File "/var/www/finance/finance-env/lib/python3.2/site-packages/SQLAlchemy-0.9.5-py3.2-linux-x86_64.egg/sqlalchemy/orm/attributes.py", line 233, in __get__
    return self.impl.get(instance_state(instance), dict_)
  File "/var/www/finance/finance-env/lib/python3.2/site-packages/SQLAlchemy-0.9.5-py3.2-linux-x86_64.egg/sqlalchemy/orm/attributes.py", line 577, in get
    value = callable_(state, passive)
  File "/var/www/finance/finance-env/lib/python3.2/site-packages/SQLAlchemy-0.9.5-py3.2-linux-x86_64.egg/sqlalchemy/orm/state.py", line 422, in __call__
    self.manager.deferred_scalar_loader(self, toload)
  File "/var/www/finance/finance-env/lib/python3.2/site-packages/SQLAlchemy-0.9.5-py3.2-linux-x86_64.egg/sqlalchemy/orm/loading.py", line 563, in load_scalar_attributes
    (state_str(state)))
sqlalchemy.orm.exc.DetachedInstanceError: Instance <FundType at 0x3b5b150> is not bound to a Session; attribute refresh operation cannot proceed

我的问题是我对金字塔很新,所以我不太确定正确的语法是什么,或者我是否应该在这个地方做这件事。我似乎无法找到任何示例,而且我不确定&#34;没有约束到会话&#34;装置

1 个答案:

答案 0 :(得分:0)

经过更多的阅读和摆弄,我终于开始工作了。

事实证明金字塔不使用显式提交语句,因为它使用事务管理器。

所需要的只是一个用于填充ID字段的flush语句。

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:
        fund_type = FundType(fdt_type_name='cash')
        DBSession.add(fund_type)
        DBSession.flush()

        fund = Fund(fds_name='Vanguard Prime Money Market Fund', fds_symbol='vmmxx', fds_fdt_fund_type_id=fund_type.fdt_fund_type_id)
        DBSession.add(fund)