cant map objects that aren't weak referencable

Issue #837 resolved
Former user created an issue

I was trying this:

from utils import Path
...
metadata = MetaData()
u_table = Table('auth_user', metadata, \                                        
    Column('id', types.Integer, primary_key=True), \                            
    Column('username', types.String(30)))                                       
f_table = Table('fellowship_file', metadata, \                                  
    Column('id', types.Integer, primary_key=True), \                            
    Column('user_id', None, schema.ForeignKey("auth_user.id")), \               
    Column('ls', types.PickleType, nullable=False))
mapper(User, u_table)                                                           
mapper(Path, f_table)
if not metadata.is_bound():                                                     
    metadata.bind = db                                                          
session = scoped_session(create_session)
stuff = session.query(Path).select_from(f_table.join(u_table)).filter(User.c.username==user).first()

And got this

Exception in thread Thread-2:
Traceback (most recent call last):
  File "threading.py", line 442, in __bootstrap
    self.run()
  File "./camper.py", line 258, in run
    stuff = session.query(Path).select_from(f_table.join(u_table)).filter(User.c.username==user).first()
  File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/query.py", line 590, in first
    ret = list(self[0:1](0:1))
  File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/query.py", line 619, in __iter__
    return self._execute_and_instances(context)
  File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/query.py", line 624, in _execute_and_instances
    return iter(self.instances(result, querycontext=querycontext))
  File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/query.py", line 680, in instances
    self.select_mapper._instance(context, row, result)
  File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/mapper.py", line 1425, in _instance
    instance = attribute_manager.new_instance(self.class_)
  File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/attributes.py", line 1001, in new_instance
    s._state = InstanceState(s)
  File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/attributes.py", line 547, in __init__
    self.obj = weakref.ref(obj, self.__cleanup)
TypeError: cannot create weak reference to 'Path' object

Thanks

Comments (6)

  1. Mike Bayer repo owner

    this is an issue with the construction of your Path class, in that it is not weak referencable. information on python weak references are here: http://www.python.org/doc/2.4.2/lib/module-weakref.html .

    Mapped classes need to subclass "object", and not any extension types or anything like that. In any case, would need to see the full construction of the "Path" class in order to give any assistance here.

  2. Former user Account Deleted
    • changed status to open
    • removed status

    Replying to zzzeek:

    this is an issue with the construction of your Path class, in that it is not weak referencable. information on python weak references are here: http://www.python.org/doc/2.4.2/lib/module-weakref.html .

    Mapped classes need to subclass "object", and not any extension types or anything like that. In any case, would need to see the full construction of the "Path" class in order to give any assistance here.

    Here it is :

    class Path(str): def init(self, path): pass

    I've reopened ticked because the code was working in 0.3 and to attract attention to my problem )

  3. Mike Bayer repo owner

    hello there -

    as I stated, the mapped class must be weak referencing by default. This is a product of the 0.4 session using weak referencing behavior. If you would like to disable this behavior, set it on your session:

    create_session(weak_identity_map=False)
    

    Otherwise, the Python string type is not weak referencable:

    >>> import weakref
    >>> x = "asdf"
    >>> weakref.ref(x)
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    TypeError: cannot create weak reference to 'str' object
    >>>
    

    the best approach is to change your Path class to subclass object.

  4. Former user Account Deleted
    • removed status
    • changed status to open

    as I stated, the mapped class must be weak referencing by default. This is a product of the 0.4 session using weak referencing behavior. If you would like to disable this behavior, set it on your session:

    {{{ create_session(weak_identity_map=False) }}}

    Most probably i'm doing something wrong :

    from sqlalchemy import create_engine, MetaData, Table, Column, types, schema
    from sqlalchemy.orm import mapper, relation, backref, scoped_session, create_session
    from utils import Path
    
    b = create_engine('postgres://me:pwd@localhost/tst')
    db.echo = True
    metadata = MetaData()
    u_table = Table('auth_user', metadata, \
        Column('id', types.Integer, primary_key=True), \
        Column('username', types.String(30)))
    f_table = Table('fellowship_file', metadata, \
        Column('id', types.Integer, primary_key=True), \
        Column('user_id', None, schema.ForeignKey("auth_user.id")), \
        Column('ls', types.PickleType, nullable=False))
    
    class User(object):
        pass
    
    mapper(User, u_table)
    mapper(Path, f_table)
    if not metadata.is_bound():
        metadata.bind = db
    session = create_session(weak_identity_map=False)
    
    user = 'me'
    
    stuff = session.query(Path).select_from(f_table.join(u_table)).filter(User.c.username==user).first()
    

    the same result :

    Traceback (most recent call last):
      File "./get.py", line 36, in ?
        stuff = session.query(Path).select_from(f_table.join(u_table)).filter(User.c.username==user).first()
      File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/query.py", line 600, in first
        ret = list(self[0:1](0:1))
      File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/query.py", line 629, in __iter__
        return self._execute_and_instances(context)
      File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/query.py", line 634, in _execute_and_instances
        return iter(self.instances(result, querycontext=querycontext))
      File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/query.py", line 689, in instances
        self.select_mapper._instance(context, row, result)
      File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/mapper.py", line 1414, in _instance
        instance = attribute_manager.new_instance(self.class_)
      File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/attributes.py", line 1001, in new_instance
        s._state = InstanceState(s)
      File "/usr/lib/python2.4/site-packages/sqlalchemy/orm/attributes.py", line 547, in __init__
        self.obj = weakref.ref(obj, self.__cleanup)
    TypeError: cannot create weak reference to 'Path' object
    
  5. Mike Bayer repo owner

    sorry, I misspoke on the "weak_identity_map" option; while that disables weak referencing within the identity map, we still have also added weak referencing to our state tracking object...this is necessary to prevent circular references from occuring. I think its too restrictive to require SA to never create weak references to mapped instances. Change your Path to subclass "object" instead.

  6. Log in to comment