exceptions.AttributeError: 'property' object has no attribute 'type_map' trying to query from a @classmethod

Issue #1115 resolved
Former user created an issue

I'm really not sure what's triggering this, but if I have a fancy object mapped to a table:

t_Customers = Table('customers', metadata,
    Column('customer_id', types.Integer, primary_key=True),
    Column('name', types.Unicode(100), nullable=False),
...
)

class Customer(object):
    primary_key = 'customer_id'
    @classmethod
    def get(cls, pk, *args):
        q = meta.Session.query(cls)
        if args:
            q = q.filter(*args)
        if isinstance(cls.primary_key, str):
            assert not isinstance(pk, (list, tuple)), "The primary key is a single column %s, but the pk provided %s was not a single value" % (cls.primary_key, pk)
            return q.filter(getattr(cls, cls.primary_key) == pk).one()
        if isinstance(cls.primary_key, (list, tuple)):
            assert isinstance(pk, (list, tuple)), "The primary key is multiple columns %s, but the pk provided %s was not a list or tuple" % (cls.primary_key, pk)
            assert len(cls.primary_key) == len(pk), "The primary key is %d columns, but only %d were provided" % (len(cls.primary_key), len(pk))
            #This is just a guess
            for i, col in enumerate(self.primary_key):
                q = q.filter(getattr(cls, col) == pk[i](i))
            return q.one()

orm.mapper(Customer, t_Customers)

Insert a row into the table, and then try to call the get method to retrieve that row:

c = Customer()
c.name = u"Some silly customer name"

Session.save(c)
cid = c.customer_id
Session.flush()

c = Customer.get(cid)

This will sometimes fail with "exceptions.AttributeError: 'property' object has no attribute 'type_map'"

Here's the full stack trace:

File 'pylons_project/controllers/customers.py', line 268 in sendScheduled
  c.customer = model.customers.Customer.get(caff.customer_id)
File 'pylons_project/model/core.py', line 33 in get
  q = meta.Session.query(cls)
File 'site-packages/SQLAlchemy-0.5.0beta1-py2.4.egg/sqlalchemy/orm/scoping.py', line 107 in do
  return getattr(self.registry(), name)(*args, **kwargs)
File 'site-packages/SQLAlchemy-0.5.0beta1-py2.4.egg/sqlalchemy/orm/session.py', line 894 in query
  return self._query_cls(entities, self, **kwargs)
File 'site-packages/SQLAlchemy-0.5.0beta1-py2.4.egg/sqlalchemy/orm/query.py', line 97 in __init__
  self.__setup_aliasizers(self._entities)
File 'site-packages/SQLAlchemy-0.5.0beta1-py2.4.egg/sqlalchemy/orm/query.py', line 111 in __setup_aliasizers
  mapper, selectable, is_aliased_class = _entity_info(entity, ent.entity_name)
File 'site-packages/SQLAlchemy-0.5.0beta1-py2.4.egg/sqlalchemy/orm/util.py', line 398 in _entity_info
  mapper = class_mapper(entity, entity_name, compile)
File 'site-packages/SQLAlchemy-0.5.0beta1-py2.4.egg/sqlalchemy/orm/util.py', line 488 in class_mapper
  mapper = mapper.compile()
File 'site-packages/SQLAlchemy-0.5.0beta1-py2.4.egg/sqlalchemy/orm/mapper.py', line 370 in compile
  mapper.__initialize_properties()
File 'site-packages/SQLAlchemy-0.5.0beta1-py2.4.egg/sqlalchemy/orm/mapper.py', line 391 in __initialize_properties
  prop.init(key, self)
File 'site-packages/SQLAlchemy-0.5.0beta1-py2.4.egg/sqlalchemy/orm/interfaces.py', line 378 in init
  self.do_init()
File 'site-packages/SQLAlchemy-0.5.0beta1-py2.4.egg/sqlalchemy/orm/properties.py', line 210 in do_init
  strategies.DefaultColumnLoader(self)._register_attribute(None, None, False, self.comparator_factory, proxy_property=self.descriptor)
File 'site-packages/SQLAlchemy-0.5.0beta1-py2.4.egg/sqlalchemy/orm/strategies.py', line 37 in _register_attribute
  proxy_property=proxy_property
File 'site-packages/SQLAlchemy-0.5.0beta1-py2.4.egg/sqlalchemy/orm/unitofwork.py', line 88 in register_attribute
  return attributes.register_attribute(class_, key, *args, **kwargs)
File 'site-packages/SQLAlchemy-0.5.0beta1-py2.4.egg/sqlalchemy/orm/attributes.py', line 1407 in register_attribute
  descriptor = proxy_type(key, proxy_property, comparator, parententity)
File 'site-packages/SQLAlchemy-0.5.0beta1-py2.4.egg/sqlalchemy/orm/attributes.py', line 144 in __init__
  self.descriptor = self.user_prop = descriptor
File 'site-packagesupresent/upresent/upresent/model/vertical.py', line 168 in _set_value
  if py_type not in self.type_map:
File 'site-packages/SQLAlchemy-0.5.0beta1-py2.4.egg/sqlalchemy/orm/attributes.py', line 172 in __getattr__
  return getattr(descriptor, attribute)
AttributeError: 'property' object has no attribute 'type_map'

I can put a breakpoint before the call, and run the same line either immediately before or immediately after the traceback. The cls object is set correctly. Doesn't matter if I comment out the extra filtering or not.

Comments (2)

  1. Former user Account Deleted

    I failed to mention that my customer class is really based on the "dict-like" vertical example. It seems to be failing on the "value" property. Strangely when I breakpoint, python tells me that the value property is unbound when I look at the class object.

  2. Mike Bayer repo owner

    it looks like your application is accesssing self.type_map as a column value, but in fact self is the class so you're getting the InstrumentedAttribute. the part of your code which is failing (line 168 of vertical.py) is not present in your example above. There's no bug in SA here unless a more succinct failure case can be posted; you can try posting your full code on the mailing list to get more help.

  3. Log in to comment