On 8/30/15 1:58 PM, r...@rosenfeld.to 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+unsubscr...@googlegroups.com
<mailto:sqlalchemy+unsubscr...@googlegroups.com>.
To post to this group, send email to sqlalchemy@googlegroups.com
<mailto:sqlalchemy@googlegroups.com>.
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.