Closed zzzeek closed 6 years ago
Original comment by Michael Bayer (Bitbucket: zzzeek, GitHub: zzzeek):
another failing test:
from sqlalchemy import *
metadata = BoundMetaData('sqlite://')
studentTbl = Table('student', metadata, Column('name', String(20), primary_key=True))
courseTbl = Table('course', metadata, Column('name', String(20), primary_key=True))
enrolTbl = Table('enrol', metadata,
Column('student_id', String(20), ForeignKey('student.name'),primary_key=True),
Column('course_id', String(20), ForeignKey('course.name'), primary_key=True))
metadata.create_all()
class Student(object):
def __init__(self, name=''):
self.name = name
class Course(object):
def __init__(self, name=''):
self.name = name
Student.mapper = mapper(Student, studentTbl)
Course.mapper = mapper(Course, courseTbl, properties = {
'students': relation(Student.mapper, enrolTbl, lazy=True, backref='courses')
})
sess = create_session()
s1 = Student('Student1')
c1 = Course('Course1')
c2 = Course('Course2')
c3 = Course('Course3')
s1.courses.append(c1)
s1.courses.append(c2)
c3.students.append(s1)
sess.save(s1)
sess.flush()
sess.delete(s1)
sess.flush()
assert enrolTbl.count().execute() == 0
Original comment by Michael Bayer (Bitbucket: zzzeek, GitHub: zzzeek):
in case you feel like playing with this, line 248 of sqlalchemy/orm/dependency.py is exactly where this happens :
if self.is_backref:
# if we are the "backref" half of a two-way backref
# relationship, let the other mapper handle inserting the rows
return
the solution involves the two corresponding DependencyProcessors being aware of each other, and either coexisting within the UOWTransaction and somehow insuring that only one of them does the many-to-many update of the rows, or checking if the other one is not present and then placing itself in the UOWTransaction.
Originally reported by: Joona Kulmala (Bitbucket: joona, GitHub: joona)
In my opinion obj.flush() should also commit changes between it's ManyToMany-relations. Now it works only from "active" side of relation (Foo in this example). objectstore.flush() would obviously do the trick, but that is something that id wouldn't like to do at my Web Framework's controller. obj.save() or obj.flush() would be much more logical.