Hi all,

Are there any best practices/caveats for overloading attribute access with
declarative sqlalchemy?  I feel like the checks in setattr and getattr are
very hacky and are occasionally giving me strange surprises...

from sqlalchemy import Integer, String, Column, create_engine, PickleType
from sqlalchemy.orm import Session
from sqlalchemy.ext.declarative import declarative_base


Base = declarative_base()

class Foo(Base):
    __tablename__ = 'foo'
    id = Column(Integer, primary_key=True)
    _instance_dict = Column(PickleType(mutable=True))
    name = Column(String)

    def __init__(self, name):
        self._instance_dict = {}
        self.name = name

    def __setattr__(self, key, value):
        if (key in self.__dict__ or key in self.__class__.__dict__ or
                not hasattr(self, '_sa_instance_state') or
                'AssociationProxy' in key):
            # handle class-level attrs (like Columns) using default behavior
            print 'setattr normal', key, value
            Base.__setattr__(self, key, value)
        else:
            # regular python objects attached to as an attribute go to
pickled instance dict
            print 'setattr other', key, value
            self._instance_dict[key] = value

    def __getattr__(self, key):
        # use default behavior for looking up the dicts themselves
        if key == '_instance_dict' and key not in self.__dict__:
            self._sa_instance_state.initialize(key)
            return getattr(self, key)

        # check for the key in regular python object dict and sqlobjects
dict
        try:
            return self._instance_dict[key]
        except KeyError:
            return Base.__getattr__(self, key)


engine = create_engine('sqlite://', echo=True)
Base.metadata.create_all(engine)

session = Session(engine)


# create a new animal
a = Foo('aardvark')
a.test = 10

session.add(a)
session.commit()
session.close()

for foo in session.query(Foo):
    print foo, foo.name, foo.test

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

Reply via email to