On Sep 22, 2010, at 4:30 AM, Yap Sok Ann wrote: > This is related to topic "need 0.6_beta2-compat declarative meta" > http://groups.google.com/group/sqlalchemy/browse_thread/thread/ae7cb9d2ab0b9cca > > Prior to version 0.6, I use the following code to automatically add a > primary key if the table doesn't have one defined: > > from sqlalchemy.ext.declarative import declarative_base, > DeclarativeMeta > from sqlalchemy.schema import Column > from sqlalchemy.types import Integer > > class Meta(DeclarativeMeta): > def __init__(cls, classname, bases, dict_): > for attr in dict_.itervalues(): > if isinstance(attr, Column) and attr.primary_key: > break > else: > dict_['id'] = Column(Integer, primary_key=True) > return super(Meta, cls).__init__(classname, bases, dict_) > > Base = declarative_base(metaclass=Meta) > > Of course, that doesn't work anymore in 0.6. The suggestion from the > aforementioned threads is to replace: > > dict_['id'] = Column(Integer, primary_key=True) > > with > > cls.id = Column(Integer, primary_key=True) > > Unfortunately, that alone doesn't work in this case. The problem is > that the Base class itself will be the first one to go through the > Meta.__init__() method, so the whole thing essentially becomes: > > Base.id = Column(Integer, primary_key=True) > > For it to work, I have to wrap the code in an if-block, i.e. > > class Meta(DeclarativeMeta): > def __init__(cls, classname, bases, dict_): > if classname != 'Base': > for attr in dict_.itervalues(): > if isinstance(attr, Column) and attr.primary_key: > break > else: > cls.id = Column(Integer, primary_key=True) > return super(Meta, cls).__init__(classname, bases, dict_) > > which looks rather ugly. Is there a cleaner way to achieve this?
I didn't think metaclasses were supposed to be pretty ? Checking that you're not "the base" is pretty standard metaclass stuff. If the hardcoded name is the issue, you can look in bases: if object not in bases: or something more generic: for k in cls.__mro__[1:]: if isinstance(k, Meta): # you're a Base subclass > > -- > You received this message because you are subscribed to the Google Groups > "sqlalchemy" group. > To post to this group, send email to sqlalch...@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. > -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To post to this group, send email to sqlalch...@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.