On Sep 22, 11:37 pm, Michael Bayer <mike...@zzzcomputing.com> wrote:
> 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/ae7cb9...
>
> > 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
>
Good point. I shall stick with the name checking solution then. Thank
you for your help.

-- 
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.

Reply via email to