SQLAlchemy:'NoneType'对象在bulk_update_mappings

时间:2015-09-04 22:04:17

标签: python sqlalchemy

我一直在尝试使用SQLAlchemy ORM的bulk_update_mappings方法,但我收到了一条最无用的错误消息:

Traceback (most recent call last):
  File "/vagrant/strategies/tests/test_collectors.py", line 173, in test_collect__with_update
    provider.collect()
  File "/vagrant/strategies/models.py", line 46, in collect
    self.collector.update()
  File "/vagrant/strategies/database/collectors.py", line 60, in update
    db_session.bulk_save_objects(strategies)
  File "/usr/local/miniconda3/lib/python3.4/site-packages/sqlalchemy/orm/scoping.py", line 150, in do
    return getattr(self.registry(), name)(*args, **kwargs)
  File "/usr/local/miniconda3/lib/python3.4/site-packages/sqlalchemy/orm/session.py", line 2203, in bulk_save_objects
    return_defaults, update_changed_only)
  File "/usr/local/miniconda3/lib/python3.4/site-packages/sqlalchemy/orm/session.py", line 2340, in _bulk_save_mappings
    transaction.rollback(_capture_exception=True)
  File "/usr/local/miniconda3/lib/python3.4/site-packages/sqlalchemy/util/langhelpers.py", line 60, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "/usr/local/miniconda3/lib/python3.4/site-packages/sqlalchemy/util/compat.py", line 182, in reraise
    raise value
  File "/usr/local/miniconda3/lib/python3.4/site-packages/sqlalchemy/orm/session.py", line 2332, in _bulk_save_mappings
    isstates, update_changed_only)
  File "/usr/local/miniconda3/lib/python3.4/site-packages/sqlalchemy/orm/persistence.py", line 121, in _bulk_update
    bookkeeping=False)
  File "/usr/local/miniconda3/lib/python3.4/site-packages/sqlalchemy/orm/persistence.py", line 705, in _emit_update_statements
    value_params)
  File "/usr/local/miniconda3/lib/python3.4/site-packages/sqlalchemy/orm/persistence.py", line 998, in _postfetch
    state._expire_attributes(state.dict,
AttributeError: 'NoneType' object has no attribute '_expire_attributes'

当我使用bulk_save_objects时也会发生同样的错误,但奇怪的是bulk_insert_mappings上没有,这似乎表明我的更新存在一些问题,但文档不是很有帮助。我的猜测是它与人际关系有关,但我尝试使用完整的关系对象和他们的id来获取更新值,到目前为止还没有运气。

任何想法都将不胜感激!

1 个答案:

答案 0 :(得分:-1)

因此,我发现bulk_save_objects与其他一些ORM功能(load_only)不兼容。这是导致问题的代码的一部分:

new_data_dict = get_me_the_data_blah_blah()
existing = db_session.query(Stuff).filter_by(visible=True).options(load_only('id', 'some_unique_field'))
                                                           # THIS: ^^^^^^^^^
existing = {s.some_unique_field: s for s in existing.all()}
new = []
for d in new_data_dict:
    item = existing.get(d['some_unique_field'])
    if item is not None:
        for field, value in d.items():
            setattr(item, field, value)
    else:
        item = Strategy(provider=self.provider, **d)
    new.append(item)
db_session.bulk_save_objects(new)
db_session.commit()

因此,对于load_only(原始实现仍然使用Session.add_all),某些值从未被引用,因此从未加载,因此批量方法将它们视为{{1} }。

因此,删除None可解决问题:

load_only