6

I've added a table to a database using sqlalchemy and sqlalchemy-migrate, and when I run unit tests on unrelated code that hits the database, I get the following error:

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'

What could I have done to cause wrong in my sqlalchemy models to cause this error? The code is on Launchpad at lp:~usc-isi/nova/instance_type_metadata, revisions 1109-1115 have my changes.

I added one model to 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)')

And I added the file nova/db/sqlalchemy/migrate_repo/versions/019_add_instance_type_metadata.py

r-m-n
  • 11,095
  • 4
  • 50
  • 57
Lorin Hochstein
  • 51,296
  • 30
  • 96
  • 131
  • The error I believe is due to passing mapped class attribute to where mapper of metadata is expected. The traceback in your question is not as useful due to masking by `wrap_db_error` decorator, please provide exception logged by it (a line above `raise DBError(e)`) to see what actually happened. – Denis Otkidach May 26 '11 at 10:22
  • Fixed the traceback by removing the decorator. – Lorin Hochstein May 26 '11 at 15:20

1 Answers1

4

As you can see from traceback attribute metadata of mapped class is used internally by declarative extension for SQLAlchemy's MetaData instance, while you replaced it with your own relation (backref="metadata") with different meaning. Renaming it to something else should solve the problem.

Denis Otkidach
  • 28,521
  • 8
  • 72
  • 93
  • OK, that makes sense, and changing that to "meta" seems to fix the problem. But I don't understand why this problem doesn't occur with the existing InstanceMetadata class, which also has backref="metadata": http://bazaar.launchpad.net/~hudson-openstack/nova/trunk/view/head:/nova/db/sqlalchemy/models.py – Lorin Hochstein May 26 '11 at 19:57