Hi, I've written a class decorator to define a boilerplate __init__ on some of my models that inherit from a declarative_base superclass. The problem is that sqlalchemy.orm.instrumentation._generate_init() has already installed an __init__ and when I overwrite that, things break with "object has no attribute '_sa_instance_state'" exceptions. I've provided a sample below. It actually throws a different exception than my code but I think the root issue is the same, that is, my __init__ replaced the generated one and so the ClassManager events are not being emitted.
Is there some blessed way to add an __init__ method after a class is already defined or is that just impossible with sqlalchemy's metaprogramming environment? Love the library. Very powerful and excellent documentation. Thanks. Eric $ python Python 2.7.10 (default, May 26 2015, 04:16:29) [GCC 5.1.0] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import psycopg2 >>> import sqlalchemy >>> >>> psycopg2.__version__ '2.6 (dt dec pq3 ext lo64)' >>> conn = psycopg2.connect("dbname=dispatch_dev") >>> cur = conn.cursor() >>> cur.execute("SELECT version();") >>> cur.fetchone() ('PostgreSQL 9.4.4 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 5.1.0, 64-bit',) >>> >>> sqlalchemy.__version__ '0.9.7' >>> >>> from collections import OrderedDict >>> from decimal import Decimal >>> from sqlalchemy import Column, Integer, Numeric >>> from sqlalchemy.ext.declarative import declarative_base >>> >>> def licensed(licenses): ... def decorate(cls): ... def ___init__(self, **kwargs): ... for k, v in self.licenses.items(): ... kwargs.setdefault('{}_license_rate'.format(k), v) ... super(cls, self).__init__(**kwargs) ... cls.__init__ = ___init__ ... for k, v in licenses.items(): ... licenses[k] = Decimal(v) ... cls.licenses = licenses ... for license in licenses: ... setattr(cls, '{}_license_rate'.format(license), Column( Numeric, nullable=False)) ... return cls ... return decorate ... >>> >>> Base = declarative_base() >>> >>> @licensed(OrderedDict((('foo', 100), ('bar', 150)))) ... class Instance_Link(Base): ... __tablename__ = 'instance_link' ... id = Column(Integer, primary_key=True) ... >>> Instance_Link(foo_license_rate=50) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 6, in ___init__ File "(...)/env/lib/python2.7/site-packages/sqlalchemy/ext/declarative/base.py", line 526, in _declarative_constructor setattr(self, k, kwargs[k]) File "(...)/env/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 225, in __set__ self.impl.set(instance_state(instance), AttributeError: 'NoneType' object has no attribute 'set' >>> -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.