【问题标题】:sqlalchemy: "Neither 'InstrumentedAttribute' object nor 'Comparator' object has an attribute" errorsqlalchemy:“'InstrumentedAttribute' 对象和 'Comparator' 对象都没有属性”错误
【发布时间】:2011-05-25 21:01:42
【问题描述】:

我使用 sqlalchemy 和 sqlalchemy-migrate 向数据库添加了一个表,当我对命中数据库的不相关代码运行单元测试时,我收到以下错误:

Traceback (most recent call last):
  File "/Users/lorin/nova/instance_type_metadata/.nova-venv/lib/python2.6/site-packages/nose/suite.py", line 208, in run
    self.setUp()
  File "/Users/lorin/nova/instance_type_metadata/.nova-venv/lib/python2.6/site-packages/nose/suite.py", line 291, in setUp
    self.setupContext(ancestor)
  File "/Users/lorin/nova/instance_type_metadata/.nova-venv/lib/python2.6/site-packages/nose/suite.py", line 314, in setupContext
    try_run(context, names)
  File "/Users/lorin/nova/instance_type_metadata/.nova-venv/lib/python2.6/site-packages/nose/util.py", line 478, in try_run
    return func()
  File "/Users/lorin/nova/metadata-debugging/nova/tests/__init__.py", line 62, in setup
    FLAGS.vpn_start,
  File "/Users/lorin/nova/metadata-debugging/nova/network/manager.py", line 577, in create_networks
    network_ref = db.network_get_by_cidr(context, cidr)
  File "/Users/lorin/nova/metadata-debugging/nova/db/api.py", line 628, in network_get_by_cidr
    return IMPL.network_get_by_cidr(context, cidr)
  File "/Users/lorin/nova/metadata-debugging/nova/db/sqlalchemy/api.py", line 99, in wrapper
    return f(*args, **kwargs)
  File "/Users/lorin/nova/metadata-debugging/nova/db/sqlalchemy/api.py", line 1308, in network_get_by_cidr
    result = session.query(models.Network).\
  File "/Users/lorin/nova/instance_type_metadata/.nova-venv/lib/python2.6/site-packages/sqlalchemy/orm/session.py", line 873, in query
    return self._query_cls(entities, self, **kwargs)
  File "/Users/lorin/nova/instance_type_metadata/.nova-venv/lib/python2.6/site-packages/sqlalchemy/orm/query.py", line 92, in __init__
    self._set_entities(entities)
  File "/Users/lorin/nova/instance_type_metadata/.nova-venv/lib/python2.6/site-packages/sqlalchemy/orm/query.py", line 101, in _set_entities
    self._setup_aliasizers(self._entities)
  File "/Users/lorin/nova/instance_type_metadata/.nova-venv/lib/python2.6/site-packages/sqlalchemy/orm/query.py", line 116, in _setup_aliasizers
    _entity_info(entity)
  File "/Users/lorin/nova/instance_type_metadata/.nova-venv/lib/python2.6/site-packages/sqlalchemy/orm/util.py", line 536, in _entity_info
    mapper = mapper.compile()
  File "/Users/lorin/nova/instance_type_metadata/.nova-venv/lib/python2.6/site-packages/sqlalchemy/orm/mapper.py", line 805, in compile
    mapper._post_configure_properties()
  File "/Users/lorin/nova/instance_type_metadata/.nova-venv/lib/python2.6/site-packages/sqlalchemy/orm/mapper.py", line 834, in _post_configure_properties
    prop.init()
  File "/Users/lorin/nova/instance_type_metadata/.nova-venv/lib/python2.6/site-packages/sqlalchemy/orm/interfaces.py", line 493, in init
    self.do_init()
  File "/Users/lorin/nova/instance_type_metadata/.nova-venv/lib/python2.6/site-packages/sqlalchemy/orm/properties.py", line 839, in do_init
    self._process_dependent_arguments()
  File "/Users/lorin/nova/instance_type_metadata/.nova-venv/lib/python2.6/site-packages/sqlalchemy/orm/properties.py", line 883, in _process_dependent_arguments
    setattr(self, attr, getattr(self, attr)())
  File "/Users/lorin/nova/instance_type_metadata/.nova-venv/lib/python2.6/site-packages/sqlalchemy/ext/declarative.py", line 1078, in return_cls
    x = eval(arg, globals(), d)
  File "<string>", line 1, in <module>
  File "/Users/lorin/nova/instance_type_metadata/.nova-venv/lib/python2.6/site-packages/sqlalchemy/util.py", line 76, in __missing__
    self[key] = val = self.creator(key)
  File "/Users/lorin/nova/instance_type_metadata/.nova-venv/lib/python2.6/site-packages/sqlalchemy/ext/declarative.py", line 1070, in access_cls
    elif key in cls.metadata.tables:
  File "/Users/lorin/nova/instance_type_metadata/.nova-venv/lib/python2.6/site-packages/sqlalchemy/orm/attributes.py", line 138, in __getattr__
    key)
AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object has an attribute 'tables'

我可以做些什么来导致我的 sqlalchemy 模型出现错误而导致此错误?代码在启动板上lp:~usc-isi/nova/instance_type_metadata,修订版 1109-1115 有我的更改。

我给nova/db/sqlalchemy/models.py添加了一个模型:

class InstanceTypeMetadata(BASE, NovaBase):
    """Represents a metadata key/value pair for an instance_type"""
    __tablename__ = 'instance_type_metadata'
    id = Column(Integer, primary_key=True)
    key = Column(String(255))
    value = Column(String(255))
    instance_type_id = Column(Integer, ForeignKey('instance_types.id'),
                              nullable=False)
    instance_type = relationship(InstanceTypes, backref="metadata",
                 foreign_keys=instance_type_id,
                 primaryjoin='and_('
                 'InstanceTypeMetadata.instance_type_id == InstanceTypes.id,'
                 'InstanceTypeMetadata.deleted == False)')

我添加了文件nova/db/sqlalchemy/migrate_repo/versions/019_add_instance_type_metadata.py

【问题讨论】:

  • 我认为该错误是由于将映射类属性传递到预期元数据映射器的位置。由于wrap_db_error 装饰器的屏蔽,您问题中的回溯没有那么有用,请提供由它记录的异常(raise DBError(e) 上方的一行)以查看实际发生的情况。
  • 通过移除装饰器修复了回溯问题。

标签: python sqlalchemy sqlalchemy-migrate


【解决方案1】:

从追溯属性metadata 可以看出,映射类的MetaData 实例在内部由SQLAlchemy 的MetaData 实例的声明性扩展使用,而您将其替换为具有不同含义的自己的关系(backref="metadata")。将其重命名为其他名称应该可以解决问题。

【讨论】:

猜你喜欢
  • 2021-08-31
  • 1970-01-01
  • 2021-02-12
  • 2015-05-29
  • 2016-02-22
  • 2017-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多