"teacher" has two many-to-one relationships with "student".
A teacher can have a favorite student and a worst student.
A student can be the favorite (or worst) of many teachers
1) Error is not surprising, since there is nothing to indicate whether
"favorite" relationship uses "favorite_id" ForeignKey or "worst_id"
ForeignKey.
sqlalchemy.exc.ArgumentError: Could not determine join condition between
parent/child tables on relationship Teacher.favorite. Specify a
'primaryjoin' expression. If 'secondary' is present, 'secondaryjoin' is
needed as well.
How should one indicate association between relationship and ForeignKey
column?
2) When I comment out worst_id:
###worst_id = Column(Integer, ForeignKey('student.id')) # for
many-to-one
No error is reported. But with worst_id Column commented out, running the
second module below produces weird result. Before the commit teacher 1 has
a favorite student and different worst student. After commit, the favorite
relationship is corrupted, favorite and worst are now the same student.
True the mto.py module is not good, but producing corrupt data rather than
gracefully raising an exception seems like a bug.
result with line commented out ###worst_id = Column(Integer, ForeignKey('
student.id')) # for many-to-one
('sA likes_me_best:', [<mto.Teacher object at 0xb76b3f8c>], '
sA.likes_me_least', [])
('sB likes_me_best:', [], ' sB.likes_me_least', [<mto.Teacher object at
0xb76b3f8c>])
('t1.favorite_id:', None, 't1.favorite:', <mto.Student object at
0xb7344e4c>, 't1.worst:', <mto.Student object at 0xb7344e8c>)
('sA.id:', None, 'sB.id:', None)
============== AFTER COMMIT ==================
('sA likes_me_best:', [], ' sA.likes_me_least', [])
('sB likes_me_best:', [<mto.Teacher object at 0xb76b3f8c>], '
sB.likes_me_least', [<mto.Teacher object at 0xb76b3f8c>])
('t1.favorite_id:', 2, 't1.favorite:', <mto.Student object at 0xb7344e8c>,
't1.worst:', <mto.Student object at 0xb7344e8c>)
('sA.id:', 1, 'sB.id:', 2)
mto.py
---------
#!/usr/bin/env python
from sqlalchemy import Table, Column, Integer, ForeignKey
from sqlalchemy.orm import relationship, backref
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Teacher(Base):
__tablename__ = 'parent'
id = Column(Integer, primary_key=True)
favorite_id = Column(Integer, ForeignKey('student.id')) # for
many-to-one
favorite = relationship("Student", backref="likes_me_best") # my
favorite student
worst_id = Column(Integer, ForeignKey('student.id')) # for many-to-one
worst = relationship("Student", backref="likes_me_least") # my worst
student
class Student(Base):
__tablename__ = 'student'
id = Column(Integer, primary_key=True)
====================================
#!/usr/bin/env python
import mto
import sqlalchemy
t1 = mto.Teacher()
#t2 = mto.Teacher()
sA = mto.Student()
sB = mto.Student()
t1.favorite = sA
t1.worst = sB
print("sA likes_me_best:",sA.likes_me_best, "
sA.likes_me_least",sA.likes_me_least)
print("sB likes_me_best:",sB.likes_me_best, "
sB.likes_me_least",sB.likes_me_least)
print("t1.favorite_id:", t1.favorite_id, "t1.favorite:", t1.favorite,
"t1.worst:", t1.worst)
print("sA.id:", sA.id, "sB.id:", sB.id)
sqla_engine = sqlalchemy.create_engine('sqlite:///:memory:', echo=False)
mto.Base.metadata.create_all(sqla_engine)
Session = sqlalchemy.orm.sessionmaker(bind=sqla_engine)
session = Session()
session.add(t1)
session.commit()
print("\n ============== AFTER COMMIT ==================\n")
print("sA likes_me_best:",sA.likes_me_best, "
sA.likes_me_least",sA.likes_me_least)
print("sB likes_me_best:",sB.likes_me_best, "
sB.likes_me_least",sB.likes_me_least)
print("t1.favorite_id:", t1.favorite_id, "t1.favorite:", t1.favorite,
"t1.worst:", t1.worst)
print("sA.id:", sA.id, "sB.id:", sB.id)
--
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en.