Thanks On Sunday, August 30, 2015 at 10:28:58 PM UTC-5, Michael Bayer wrote: > > > > On 8/30/15 1:58 PM, r...@rosenfeld.to <javascript:> wrote: > > Hi All, > > I'm trying to replace string definitions prgrammatically where possible. > I have the following working: > > from sqlalchemy import Column > from sqlalchemy import Integer > from sqlalchemy import ForeignKey > from sqlalchemy.orm import relationship > from sqlalchemy.ext.declarative import declarative_base > > import pprint > > > Base = declarative_base() > > > class Parent(Base): > __tablename__ = 'parent' > id = Column(Integer, primary_key=True) > children = relationship("Child", backref=__tablename__) > > > class Child(Base): > __tablename__ = 'child' > id = Column(Integer, primary_key=True) > parent_id = Column(Integer, ForeignKey('parent.id')) > > > p = Parent() > pprint.pprint('p table name: {}'.format(p.__tablename__)) > c = Child() > pprint.pprint('c table name: {}'.format(c.__tablename__)) > c.parent = p > pprint.pprint('Children: {}'.format(p.children)) > pprint.pprint('Parent: {}'.format(c.parent)) > > > But I'd like to follow the mixin example from the docs to inherit common > columns and a function for __tablename__ via the Common class. > > from sqlalchemy import Column > from sqlalchemy import Integer > from sqlalchemy import ForeignKey > from sqlalchemy.orm import relationship > from sqlalchemy.ext.declarative import declarative_base > from sqlalchemy.ext.declarative import declared_attr > > import pprint > from inflection import underscore > > > class Common(object): > @declared_attr > def __tablename__(cls): > return underscore(cls.__name__) > id = Column(Integer, primary_key=True) > > > Base = declarative_base(cls=Common) > > > class Parent(Base): > children = relationship("Child", backref=__tablename__) > > > class Child(Base): > parent_id = Column(Integer, ForeignKey('parent.id')) > > > p = Parent() > pprint.pprint('p table name: {}'.format(p.__tablename__)) > c = Child() > pprint.pprint('c table name: {}'.format(c.__tablename__)) > c.parent = p > pprint.pprint('Children: {}'.format(p.children)) > pprint.pprint('Parent: {}'.format(c.parent)) > > > > I cannot figure out how to refer to the __tablename__ property in backref > using this model. > > well it needs to be a callable function that is called when the "cls", in > this case Parent, is available. It would be awkward but you'd need to do > it like this: > > @declared_attr > def children(cls): > return relationship("Child", backref=cls.__tablename__) > > this is because the way it is now, "children = relationship" needs to know > the name "Parent" which is explicitly not available yet, because you're in > a class block named "Parent" - that name isn't known to the script until > you exit that block. relationship() allows a lot of its members to be > passed as functions but backref / back_populates aren't one of them because > these have to do with the class mapping, rather than tables/columns which > is why the deferred approach is provided. > > You can make your own function that generates that @declared_attr in one > step to save on verbosity. > > > > > > If I refer to Base.__tablename__ or Common.__tablename__, it gets the > wrong value. Can you help me fix this? > > Thanks, > Rob > -- > 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+...@googlegroups.com <javascript:>. > To post to this group, send email to sqlal...@googlegroups.com > <javascript:>. > Visit this group at http://groups.google.com/group/sqlalchemy. > For more options, visit https://groups.google.com/d/optout. > > >
-- 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.