On 09/06/2016 11:12 AM, TomS. wrote:
Hi,
In my model I am not allowed to use FK. I've been trying to figure out
how one to many/many to one relationship should be properly defined or
in which class to be sure that it works as expected. I've recently used
very similar example - here it is:
class DepTest(db.Model):
__tablename__ = u'deptest'
__bind_key__ = u'section'
department_pk_id = db.Column(db.Integer, primary_key=True)
department_id = db.Column(db.Integer)
department_name = db.Column(db.String(1000))
# @declared_attr
# def ppl(clss):
# return relationship(u'Level1',
# primaryjoin=u'and_(Level1.department_id==DepTest.department_id,'
# u'
Level1.person_include_flag==1)',
# foreign_keys=[clss.department_id],
# backref=u'department')
class PPLTest(db.Model):
__abstract__ = True
person_pk_id = db.Column(db.Integer, primary_key=True)
person_name = db.Column(db.String(1000))
person_surname = db.Column(db.String(1000))
person_include_flag = db.Column(db.Integer)
department_id = db.Column(db.Integer)
@hybrid_property
def person_name_surname(self):
return self.person_name + u' ' + self.person_surname
class Level1(PPLTest):
__tablename__ = u'ppl_level1'
__bind_key__ = u'section'
# @declared_attr
# def department(clss):
# return relationship(u'DepTest',
# primaryjoin=u'and_(Level1.department_id==DepTest.department_id,'
# u'
Level1.person_include_flag==1)',
# foreign_keys=[clss.department_id],
# backref=u'ppl')
I am looking for the comprehensive answer to be sure that result is not
coincidental.
If @declared_attr part in DepTest is uncommented (while in Level1 is
commented), I get only one person/scalar (although there are more ppl)
after running:
q = DepTest.query.all()
print q[0].ppl
and list here:
q = Level1.query.all()
print q[1].department
In case if @declared_attr part in Level1 is uncommented (while in
DepTest is commented) it behaves according to my intentions:
# list
q = DepTest.query.all()
print q[0].ppl
# scalar
q = Level1.query.all()
print q[1].department
In docs the difference between 1 to many, many to 1 depends on (if I
understand it correctly) in which class ForeignKey is defined (because
usage of backref creates bidirectional behaviour). So what is the rule
in the cases without FK? Should @declared_attr be put in class which
represents "many" entities (thus get ppl as a list).
to reduce confusion I'd use the foreign() annotation in the primary join
directly:
@declared_attr
def department(clss):
return relationship(
u'DepTest',
primaryjoin=u'and_(foreign(Level1.department_id)==DepTest.department_id,'
u'Level1.person_include_flag==1)',
backref=u'ppl')
the reason you're getting opposite results is because you're setting
foreign_keys to "clss.department_id" on both sides, which has the
opposite meaning. In this case, you indicate you would have the FOREIGN
KEY constraint on Level1.department_id. So on DepTest you'd need to
have "foreign_keys="Level1.department_id" as well.
Also because you are using backref, you should only use one or the other
of these relationships - using both will create a collision as backref
is already building a second relationship.
Any links to doc, info would be very helpful.
--
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 https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.