On Wednesday, October 30, 2013 9:34:38 AM UTC-6, Michael Bayer wrote: > > > On Oct 30, 2013, at 10:58 AM, jkmacc <[email protected] <javascript:>> > wrote: > > Hi all, > > I've got a module defining a number of abstract declarative classes. They > represent standard generic classes/tables. > I'd like to take one of these abstract classes and subclass more than > once, adding a 'schema' name to '__table_args__' and a '__tablename__'. This > to me is like making a specific 'realization' of the abstract class > structure. I want to keep the columns (with info dictionaries) and > constraints in the abstract class, but make a 'realization' of the abstract > class as different tables with different names and schema. > > When I do this, however, I get warnings and errors I don't understand. Here's > an example: > > % ------------------------ code > -------------------------------------------------------------------------- > from sqlalchemy import Column, Numeric, String, Date, PrimaryKeyConstraint > from sqlalchemy.ext.declarative import declarative_base > > Base = declarative_base() > > class Students(Base): > __abstract__ = True > __table_args__ = (PrimaryKeyConstraint(u'stid', u'last_name'),) > > stid = Column(Numeric(9, 0, False), nullable=False, info={'format': > '9.2f'}) > first_name = Column(String(30), info={'format': '30.30s'}) > last_name = Column(String(30), info={'format': '30.30s'}) > description = Column(String(80), info={'format': '80.80s'}) > lddate = Column(Date, info={'format': '%Y-%m-%d %H:%M:%S'}) > > > class MyStudents(Students): > __tablename__ = 'students' > __table_args__ = Students.__table_args__ + ({'__schema__': 'me'},) > > class OldStudents(Students): > __tablename__ = 'oldstudents' > __table_args__ = Students.__table_args__ + ({'__schema__': 'me'},) > > class OtherStudents(Students): > __tablename__ = 'students' > __table_args__ = Students.__table_args__ + ({'__schema__': 'other'},) > % ------------------------ end code ——————————————————————————————————— > > > > well the “schema” argument on Table is called “schema”, not “__schema__”, > and the __table_args__ are not copied to each subclass (e.g. you’re using > the same PrimaryKeyConstraint object on three different Table objects) so > you’d want to use @declared_attr + def __table_args__(cls) for that. > > > Hmm... The 'schema' problem was my dumb mistake, but I still haven't found a use of @declared_attr that solves my problem. It looks like, by the time I get to my OldStudents or anything afterwards, I have to redeclare almost everything in __table_args__. I've tried modifying the base with a @declared_attr that merges __table_args__ down the class hierarchy, like in https://groups.google.com/forum/#!topic/sqlalchemy/KybuUktY3t8, but I just get recursion problems. I'd hoped that I could declare most everything once in the abstract class, but it seems that what you're saying is that this isn't true.
The closest thing I've found is something like a Table copy function from https://groups.google.com/forum/#!topic/sqlalchemy/f1D1LBkaWCE, where I'd copy and tweak the __table__ name and schema from a non-abstract version of Students, and do an on-the-fly "hybrid" declaration using the new __table__. This use case seemed common enough that I thought I was missing something obvious, but the answer may be that it'll take a bit more hacking on my part. Thanks again, Jon -- 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 [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/groups/opt_out.
