⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 manytomany.py

📁 SQLAlchemy. 经典的Python ORM框架。学习必看。
💻 PY
字号:
import testenv; testenv.configure_for_tests()from sqlalchemy import *from sqlalchemy.orm import *from testlib import *from sqlalchemy import exceptionsclass Place(object):    '''represents a place'''    def __init__(self, name=None):        self.name = name    def __str__(self):        return "(Place '%s')" % self.name    def __repr__(self):        return str(self)class PlaceThingy(object):    '''represents a thingy attached to a Place'''    def __init__(self, name=None):        self.name = nameclass Transition(object):    '''represents a transition'''    def __init__(self, name=None):        self.name = name        self.inputs = []        self.outputs = []    def __repr__(self):        return object.__repr__(self)+ " " + repr(self.inputs) + " " + repr(self.outputs)class M2MTest(ORMTest):    def define_tables(self, metadata):        global place        place = Table('place', metadata,            Column('place_id', Integer, Sequence('pid_seq', optional=True), primary_key=True),            Column('name', String(30), nullable=False),            )        global transition        transition = Table('transition', metadata,            Column('transition_id', Integer, Sequence('tid_seq', optional=True), primary_key=True),            Column('name', String(30), nullable=False),            )        global place_thingy        place_thingy = Table('place_thingy', metadata,            Column('thingy_id', Integer, Sequence('thid_seq', optional=True), primary_key=True),            Column('place_id', Integer, ForeignKey('place.place_id'), nullable=False),            Column('name', String(30), nullable=False)            )        # association table #1        global place_input        place_input = Table('place_input', metadata,            Column('place_id', Integer, ForeignKey('place.place_id')),            Column('transition_id', Integer, ForeignKey('transition.transition_id')),            )        # association table #2        global place_output        place_output = Table('place_output', metadata,            Column('place_id', Integer, ForeignKey('place.place_id')),            Column('transition_id', Integer, ForeignKey('transition.transition_id')),            )        global place_place        place_place = Table('place_place', metadata,            Column('pl1_id', Integer, ForeignKey('place.place_id')),            Column('pl2_id', Integer, ForeignKey('place.place_id')),            )    def testerror(self):        mapper(Place, place, properties={            'transitions':relation(Transition, secondary=place_input, backref='places')        })        mapper(Transition, transition, properties={            'places':relation(Place, secondary=place_input, backref='transitions')        })        try:            compile_mappers()            assert False        except exceptions.ArgumentError, e:            assert str(e) in [                "Error creating backref 'transitions' on relation 'Transition.places (Place)': property of that name exists on mapper 'Mapper|Place|place'",                "Error creating backref 'places' on relation 'Place.transitions (Transition)': property of that name exists on mapper 'Mapper|Transition|transition'"            ]    def testcircular(self):        """tests a many-to-many relationship from a table to itself."""        Place.mapper = mapper(Place, place)        Place.mapper.add_property('places', relation(            Place.mapper, secondary=place_place, primaryjoin=place.c.place_id==place_place.c.pl1_id,            secondaryjoin=place.c.place_id==place_place.c.pl2_id,            order_by=place_place.c.pl2_id,            lazy=True,            ))        sess = create_session()        p1 = Place('place1')        p2 = Place('place2')        p3 = Place('place3')        p4 = Place('place4')        p5 = Place('place5')        p6 = Place('place6')        p7 = Place('place7')        [sess.save(x) for x in [p1,p2,p3,p4,p5,p6,p7]]        p1.places.append(p2)        p1.places.append(p3)        p5.places.append(p6)        p6.places.append(p1)        p7.places.append(p1)        p1.places.append(p5)        p4.places.append(p3)        p3.places.append(p4)        sess.flush()        sess.clear()        l = sess.query(Place).order_by(place.c.place_id).all()        (p1, p2, p3, p4, p5, p6, p7) = l        assert p1.places == [p2,p3,p5]        assert p5.places == [p6]        assert p7.places == [p1]        assert p6.places == [p1]        assert p4.places == [p3]        assert p3.places == [p4]        assert p2.places == []        for p in l:            pp = p.places            print "Place " + str(p) +" places " + repr(pp)        [sess.delete(p) for p in p1,p2,p3,p4,p5,p6,p7]        sess.flush()    def testdouble(self):        """tests that a mapper can have two eager relations to the same table, via        two different association tables.  aliases are required."""        Place.mapper = mapper(Place, place, properties = {            'thingies':relation(mapper(PlaceThingy, place_thingy), lazy=False)        })        Transition.mapper = mapper(Transition, transition, properties = dict(            inputs = relation(Place.mapper, place_output, lazy=False),            outputs = relation(Place.mapper, place_input, lazy=False),            )        )        tran = Transition('transition1')        tran.inputs.append(Place('place1'))        tran.outputs.append(Place('place2'))        tran.outputs.append(Place('place3'))        sess = create_session()        sess.save(tran)        sess.flush()        sess.clear()        r = sess.query(Transition).all()        self.assert_unordered_result(r, Transition,            {'name': 'transition1',            'inputs': (Place, [{'name':'place1'}]),            'outputs': (Place, [{'name':'place2'}, {'name':'place3'}])            })    def testbidirectional(self):        """tests a many-to-many backrefs"""        Place.mapper = mapper(Place, place)        Transition.mapper = mapper(Transition, transition, properties = dict(            inputs = relation(Place.mapper, place_output, lazy=True, backref='inputs'),            outputs = relation(Place.mapper, place_input, lazy=True, backref='outputs'),            )        )        t1 = Transition('transition1')        t2 = Transition('transition2')        t3 = Transition('transition3')        p1 = Place('place1')        p2 = Place('place2')        p3 = Place('place3')        t1.inputs.append(p1)        t1.inputs.append(p2)        t1.outputs.append(p3)        t2.inputs.append(p1)        p2.inputs.append(t2)        p3.inputs.append(t2)        p1.outputs.append(t1)        sess = create_session()        [sess.save(x) for x in [t1,t2,t3,p1,p2,p3]]        sess.flush()        self.assert_result([t1], Transition, {'outputs': (Place, [{'name':'place3'}, {'name':'place1'}])})        self.assert_result([p2], Place, {'inputs': (Transition, [{'name':'transition1'},{'name':'transition2'}])})class M2MTest2(ORMTest):    def define_tables(self, metadata):        global studentTbl        studentTbl = Table('student', metadata, Column('name', String(20), primary_key=True))        global courseTbl        courseTbl = Table('course', metadata, Column('name', String(20), primary_key=True))        global enrolTbl        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))    def testcircular(self):        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)        self.assert_(len(s1.courses) == 3)        self.assert_(len(c1.students) == 1)        sess.save(s1)        sess.flush()        sess.clear()        s = sess.query(Student).filter_by(name='Student1').one()        c = sess.query(Course).filter_by(name='Course3').one()        self.assert_(len(s.courses) == 3)        del s.courses[1]        self.assert_(len(s.courses) == 2)    def test_delete(self):        """test that many-to-many table gets cleared out with deletion from the backref side"""        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().scalar() == 0class M2MTest3(ORMTest):    def define_tables(self, metadata):        global c, c2a1, c2a2, b, a        c = Table('c', metadata,            Column('c1', Integer, primary_key = True),            Column('c2', String(20)),        )        a = Table('a', metadata,            Column('a1', Integer, primary_key=True),            Column('a2', String(20)),            Column('c1', Integer, ForeignKey('c.c1'))            )        c2a1 = Table('ctoaone', metadata,            Column('c1', Integer, ForeignKey('c.c1')),            Column('a1', Integer, ForeignKey('a.a1'))        )        c2a2 = Table('ctoatwo', metadata,            Column('c1', Integer, ForeignKey('c.c1')),            Column('a1', Integer, ForeignKey('a.a1'))        )        b = Table('b', metadata,            Column('b1', Integer, primary_key=True),            Column('a1', Integer, ForeignKey('a.a1')),            Column('b2', Boolean)        )    def testbasic(self):        class C(object):pass        class A(object):pass        class B(object):pass        mapper(B, b)        mapper(A, a,            properties = {                'tbs' : relation(B, primaryjoin=and_(b.c.a1==a.c.a1, b.c.b2 == True), lazy=False),            }        )        mapper(C, c,            properties = {                'a1s' : relation(A, secondary=c2a1, lazy=False),                'a2s' : relation(A, secondary=c2a2, lazy=False)            }        )        o1 = create_session().query(C).get(1)if __name__ == "__main__":    testenv.main()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -