I happened to encounter the same issue just yesterday which mike promptly solved by implementing features of separate eagermappers.

The circular dependency comes (I believe) when a student is eagerly loading all his courses, and now for each course he loads up, that course is at the same time eagerly loading back its students.  So you can see a loop there.

So either have one class eagerly loaded and the other lazily loaded like this:

Student.mapper = mapper(Student, studentTbl)
Course.mapper = mapper(Course, courseTbl)

Student.mapper.add_property('courses',
         relation(Course.mapper, enrolTbl, lazy=True))

Course.mapper.add_property('students',
        relation(Student.mapper, enrolTbl, lazy=False))

or something like this would give a separate eager loader for both tables:

# lazy ones
Student.mapper = mapper(Student, studentTbl)
Course.mapper = mapper(Course, courseTbl)

Student.mapper.add_property('courses',
         relation(Course.mapper, enrolTbl, lazy=True))

Course.mapper.add_property('students',
        relation(Student.mapper, enrolTbl, lazy=True))

# eager ones
Student.eagermapper = Student.mapper.options(
        eagerloader('courses')
)
Course.eagermapper = Course.mapper.options(
        eagerloader('students')
)

s = Student.eagermapper.select()

I didn't test this code, but the basic concept I believe applies.  There is also a many-to-many test in the test directory that walks you through this.  Correct me if I'm wrong Mike!

HTH



On 12/3/05, Robert Leftwich <[EMAIL PROTECTED]> wrote:
It looks there is a problem in the many-to-many mapping. Using the classic
'students enrol in many courses and a course is taken by many students' as an
example:

studentTbl = Table('student', engine,
                    Column('id', Integer, primary_key=True),
                    Column('name', String))

courseTbl = Table('course', engine,
                    Column('id', Integer, primary_key=True),
                    Column('name', String))

enrolTbl = Table('enrol', engine,
                    Column('student_id', Integer,
                            ForeignKey('student.id'),
                            primary_key=True),
                    Column('course_id', Integer,
                            ForeignKey('course.id'),
                            primary_key=True))

class Student(object):
     pass


class Course(object):
     pass

Student.mapper = mapper(Student, studentTbl)
Course.mapper = mapper(Course, courseTbl)

Student.mapper.add_property('courses',
         relation(Course.mapper, enrolTbl, lazy=False))

Course.mapper.add_property('students',
        relation(Student.mapper, enrolTbl, lazy=False))

studentTbl.create()
courseTbl.create()
enrolTbl.create()

s1 = Student()
s1.id = 1
s1.name = 'Student1'

c1 = Course()
c1.id = 1
c1.name='Course1'

s1.courses.append(c1)

objectstore.commit()

s = Student.mapper.select ()

I get an error:
"Circular eager load relationship detected on Mapper|Student|student
courses{'courses': <sqlalchemy.mapping.properties.EagerLoader object at
0xb72a50cc>, 'id': <sqlalchemy.mapping.properties.ColumnProperty object at
0xb72a516c>, 'name': <sqlalchemy.mapping.properties.ColumnProperty object at
0xb72a51ac>}: None"

Am I missing something?

Note that this is using the latest svn with postgres as the db, in a previous
version the error was thrown when the objectstore.commit() was executed, now it
is in the select().

Robert



-------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc. Do you grep through log files
for problems?  Stop!  Download the new AJAX search engine that makes
searching your log files as easy as surfing the  web.  DOWNLOAD SPLUNK!
http://ads.osdn.com/?ad_id=7637&alloc_id=16865&op=click
_______________________________________________
Sqlalchemy-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users



--
---------------------------------------------------------------------------------------------------
John S. Yang

Reply via email to