Пример #1
0
    def test_orphan(self):
        """test that an entity can have two parent delete-orphan cascades, and is detected as an orphan
        when saved without a parent."""

        class Address(_fixtures.Base):
            pass

        class Home(_fixtures.Base):
            pass

        class Business(_fixtures.Base):
            pass

        mapper(Address, addresses)
        mapper(Home, homes, properties={"address": relation(Address, cascade="all,delete-orphan", single_parent=True)})
        mapper(
            Business,
            businesses,
            properties={"address": relation(Address, cascade="all,delete-orphan", single_parent=True)},
        )

        session = create_session()
        a1 = Address()
        session.add(a1)
        try:
            session.flush()
            assert False
        except orm_exc.FlushError, e:
            assert True
Пример #2
0
    def test_delete_orphan_cascades(self):
        mapper(
            A,
            a,
            properties={
                # if no backref here, delete-orphan failed until [ticket:427] was
                # fixed
                "bs": relation(B, secondary=atob, cascade="all, delete-orphan", single_parent=True)
            },
        )
        mapper(B, b, properties={"cs": relation(C, cascade="all, delete-orphan")})
        mapper(C, c)

        sess = create_session()
        b1 = B(data="b1", cs=[C(data="c1")])
        a1 = A(data="a1", bs=[b1])
        sess.add(a1)
        sess.flush()

        a1.bs.remove(b1)
        sess.flush()
        assert atob.count().scalar() == 0
        assert b.count().scalar() == 0
        assert a.count().scalar() == 1
        assert c.count().scalar() == 0
Пример #3
0
    def test_one(self):
        p_m = mapper(Part, parts)

        mapper(InheritedPart, inherited_part, properties=dict(
            part=relation(Part, lazy=False)))

        d_m = mapper(Design, design, properties=dict(
            inheritedParts=relation(InheritedPart,
                                    cascade="all, delete-orphan",
                                    backref="design")))

        mapper(DesignType, design_types)

        d_m.add_property(
            "type", relation(DesignType, lazy=False, backref="designs"))

        p_m.add_property(
            "design", relation(
                Design, lazy=False,
                backref=backref("parts", cascade="all, delete-orphan")))


        d = Design()
        sess = create_session()
        sess.add(d)
        sess.flush()
        sess.expunge_all()
        x = sess.query(Design).get(1)
        x.inheritedParts
Пример #4
0
    def test_pending_expunge(self):
        class Order(_fixtures.Base):
            pass

        class Item(_fixtures.Base):
            pass

        class Attribute(_fixtures.Base):
            pass

        mapper(Attribute, attributes)
        mapper(
            Item, items, properties=dict(attributes=relation(Attribute, cascade="all,delete-orphan", backref="item"))
        )
        mapper(Order, orders, properties=dict(items=relation(Item, cascade="all,delete-orphan", backref="order")))

        s = create_session()
        order = Order(name="order1")
        s.add(order)

        attr = Attribute(name="attr1")
        item = Item(name="item1", attributes=[attr])

        order.items.append(item)
        order.items.remove(item)

        assert item not in s
        assert attr not in s

        s.flush()
        assert orders.count().scalar() == 1
        assert items.count().scalar() == 0
        assert attributes.count().scalar() == 0
Пример #5
0
    def test_bidirectional(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.add_all((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'}])})
Пример #6
0
    def testone(self):
        """
        Tests eager load of a many-to-one attached to a one-to-many.  this
        testcase illustrated the bug, which is that when the single Company is
        loaded, no further processing of the rows occurred in order to load
        the Company's second Address object.

        """
        mapper(Address, addresses)

        mapper(Company, companies, properties={"addresses": relation(Address, lazy=False)})

        mapper(Invoice, invoices, properties={"company": relation(Company, lazy=False)})

        a1 = Address(address="a1 address")
        a2 = Address(address="a2 address")
        c1 = Company(company_name="company 1", addresses=[a1, a2])
        i1 = Invoice(date=datetime.datetime.now(), company=c1)

        session = create_session()
        session.add(i1)
        session.flush()

        company_id = c1.company_id
        invoice_id = i1.invoice_id

        session.clear()
        c = session.query(Company).get(company_id)

        session.clear()
        i = session.query(Invoice).get(invoice_id)

        eq_(c, i.company)
Пример #7
0
        def define_tables(self, metadata):
            global User, Address
            Base = decl.declarative_base(metadata=metadata)

            class User(Base, ComparableEntity):
                __tablename__ = 'users'
                id = Column(Integer, primary_key=True)
                name = Column(String(50))
            
            class Address(Base, ComparableEntity):
                __tablename__ = 'addresses'
                id = Column(Integer, primary_key=True)
                email = Column(String(50))
                user_id = Column(Integer, ForeignKey('users.id'))
                if inline:
                    if stringbased:
                        user = relation("User", primaryjoin="User.id==Address.user_id", backref="addresses")
                    else:
                        user = relation(User, primaryjoin=User.id==user_id, backref="addresses")
            
            if not inline:
                compile_mappers()
                if stringbased:
                    Address.user = relation("User", primaryjoin="User.id==Address.user_id", backref="addresses")
                else:
                    Address.user = relation(User, primaryjoin=User.id==Address.user_id, backref="addresses")
Пример #8
0
    def test_double(self):
        """test 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.add(tran)
        sess.flush()

        sess.expunge_all()
        r = sess.query(Transition).all()
        self.assert_unordered_result(r, Transition,
            {'name': 'transition1',
            'inputs': (Place, [{'name':'place1'}]),
            'outputs': (Place, [{'name':'place2'}, {'name':'place3'}])
            })
Пример #9
0
    def test_non_orphan(self):
        """test that an entity can have two parent delete-orphan cascades, and persists normally."""

        class Address(_fixtures.Base):
            pass

        class Home(_fixtures.Base):
            pass

        class Business(_fixtures.Base):
            pass

        mapper(Address, addresses)
        mapper(Home, homes, properties={"address": relation(Address, cascade="all,delete-orphan", single_parent=True)})
        mapper(
            Business,
            businesses,
            properties={"address": relation(Address, cascade="all,delete-orphan", single_parent=True)},
        )

        session = create_session()
        h1 = Home(description="home1", address=Address(street="address1"))
        b1 = Business(description="business1", address=Address(street="address2"))
        session.add_all((h1, b1))
        session.flush()
        session.expunge_all()

        eq_(session.query(Home).get(h1.id), Home(description="home1", address=Address(street="address1")))
        eq_(session.query(Business).get(b1.id), Business(description="business1", address=Address(street="address2")))
Пример #10
0
 def setup_mappers(self):
     mapper(T1, t1, properties={
         't2':relation(T2, primaryjoin=t1.c.t2id == t2.c.id)})
     mapper(T2, t2, properties={
         't1':relation(T1, primaryjoin=t2.c.t1id == t1.c.id)})
     mapper(T3, t3, properties={
         't1':relation(T1),
         't2':relation(T2)})
Пример #11
0
 def setup_mappers(self):
     mapper(Extra, extra)
     mapper(Pref, prefs, properties=dict(extra=relation(Extra, cascade="all, delete")))
     mapper(
         User,
         users,
         properties=dict(pref=relation(Pref, lazy=False, cascade="all, delete-orphan", single_parent=True)),
     )
Пример #12
0
 def test_error(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')
     })
     self.assertRaisesMessage(sa.exc.ArgumentError, "Error creating backref",
                              sa.orm.compile_mappers)
Пример #13
0
    def testtwo(self):
        """The original testcase that includes various complicating factors"""

        mapper(Phone, phone_numbers)

        mapper(Address, addresses, properties={
            'phones': relation(Phone, lazy=False, backref='address',
                               order_by=phone_numbers.c.phone_id)})

        mapper(Company, companies, properties={
            'addresses': relation(Address, lazy=False, backref='company',
                                  order_by=addresses.c.address_id)})

        mapper(Item, items)

        mapper(Invoice, invoices, properties={
            'items': relation(Item, lazy=False, backref='invoice',
                              order_by=items.c.item_id),
            'company': relation(Company, lazy=False, backref='invoices')})

        c1 = Company(company_name='company 1', addresses=[
            Address(address='a1 address',
                    phones=[Phone(type='home', number='1111'),
                            Phone(type='work', number='22222')]),
            Address(address='a2 address',
                    phones=[Phone(type='home', number='3333'),
                            Phone(type='work', number='44444')])
            ])

        session = create_session()
        session.add(c1)
        session.flush()

        company_id = c1.company_id

        session.expunge_all()

        a = session.query(Company).get(company_id)

        # set up an invoice
        i1 = Invoice(date=datetime.datetime.now(), company=a)

        item1 = Item(code='aaaa', qty=1, invoice=i1)
        item2 = Item(code='bbbb', qty=2, invoice=i1)
        item3 = Item(code='cccc', qty=3, invoice=i1)

        session.flush()
        invoice_id = i1.invoice_id

        session.expunge_all()
        c = session.query(Company).get(company_id)

        session.expunge_all()
        i = session.query(Invoice).get(invoice_id)

        eq_(c, i.company)
Пример #14
0
 def setup_mappers(self):
     mapper(C2, t2, properties={
         'c1s': relation(C1,
                         primaryjoin=t2.c.c1 == t1.c.c2,
                         uselist=True)})
     mapper(C1, t1, properties={
         'c2s': relation(C2,
                          primaryjoin=t1.c.c1 == t2.c.c2,
                          uselist=True),
         'data': relation(mapper(C1Data, t1_data))})
Пример #15
0
 def setup_mappers(self):
     mapper(Address, addresses)
     mapper(User, users, properties = dict(
         addresses = relation(Address, cascade="all, delete-orphan", backref="user"),
         orders = relation(
             mapper(Order, orders), cascade="all, delete-orphan")
     ))
     mapper(Dingaling,dingalings, properties={
         'address':relation(Address)
     })
Пример #16
0
 def setup_mappers(self):
     mapper(T1, t1, properties=dict(t2=relation(T2, cascade="all, delete-orphan", single_parent=True)))
     mapper(
         T2,
         t2,
         properties=dict(
             t3=relation(T3, cascade="all, delete-orphan", single_parent=True, backref=backref("t2", uselist=False))
         ),
     )
     mapper(T3, t3)
Пример #17
0
    def test_nesting_with_functions(self):
        mapper(Data, datas)
        mapper(Foo, foo, properties={"data": relation(Data, backref=backref("foo", uselist=False))})

        mapper(Stat, stats, properties={"data": relation(Data)})

        session = create_session()

        data = [Data(a=x) for x in range(5)]
        session.add_all(data)

        session.add_all(
            (
                Stat(data=data[0], somedata=1),
                Stat(data=data[1], somedata=2),
                Stat(data=data[2], somedata=3),
                Stat(data=data[3], somedata=4),
                Stat(data=data[4], somedata=5),
                Stat(data=data[0], somedata=6),
                Stat(data=data[1], somedata=7),
                Stat(data=data[2], somedata=8),
                Stat(data=data[3], somedata=9),
                Stat(data=data[4], somedata=10),
            )
        )
        session.flush()

        arb_data = sa.select(
            [stats.c.data_id, sa.func.max(stats.c.somedata).label("max")],
            stats.c.data_id <= 5,
            group_by=[stats.c.data_id],
        ).alias("arb")

        arb_result = arb_data.execute().fetchall()

        # order the result list descending based on 'max'
        arb_result.sort(key=lambda a: a["max"], reverse=True)

        # extract just the "data_id" from it
        arb_result = [row["data_id"] for row in arb_result]

        # now query for Data objects using that above select, adding the
        # "order by max desc" separately
        q = (
            session.query(Data)
            .options(sa.orm.eagerload("foo"))
            .select_from(datas.join(arb_data, arb_data.c.data_id == datas.c.id))
            .order_by(sa.desc(arb_data.c.max))
            .limit(10)
        )

        # extract "data_id" from the list of result objects
        verify_result = [d.id for d in q]

        eq_(verify_result, arb_result)
Пример #18
0
 def setup_mappers(self):
     # set up bi-directional eager loads
     mapper(Left, left)
     mapper(Right, right)
     mapper(Middle, middle, properties=dict(
         left=relation(Left,
                       lazy=False,
                       backref=backref('middle',lazy=False)),
         right=relation(Right,
                        lazy=False,
                        backref=backref('middle', lazy=False)))),
Пример #19
0
    def setup_mappers(self):
        mapper(Account, accounts)

        mapper(Transaction, transactions)

        mapper(Entry, entries, properties=dict(
            account=relation(Account,
                             uselist=False,
                             backref=backref('entries', lazy=True,
                                             order_by=entries.c.entry_id)),
            transaction=relation(Transaction,
                                 uselist=False,
                                 backref=backref('entries', lazy=False,
                                                 order_by=entries.c.entry_id))))
Пример #20
0
    def setup_mappers(self):
        items, item_keywords, keywords = self.tables.get_all(
            'items', 'item_keywords', 'keywords')

        mapper(Keyword, keywords)
        mapper(KeywordAssociation, item_keywords, properties={
            'keyword':relation(Keyword, lazy=False)},
               primary_key=[item_keywords.c.item_id, item_keywords.c.keyword_id],
               order_by=[item_keywords.c.data])

        mapper(Item, items, properties={
            'keywords' : relation(KeywordAssociation,
                                  cascade="all, delete-orphan")
        })
Пример #21
0
    def testpostupdate_m2o(self):
        """A cycle between two rows, with a post_update on the many-to-one"""
        mapper(Ball, ball)
        mapper(Person, person, properties=dict(
            balls=relation(Ball,
                           primaryjoin=ball.c.person_id == person.c.id,
                           remote_side=ball.c.person_id,
                           post_update=False,
                           cascade="all, delete-orphan"),
            favorite=relation(Ball,
                              primaryjoin=person.c.favorite_ball_id == ball.c.id,
                              remote_side=person.c.favorite_ball_id,
                              post_update=True)))

        b = Ball(data='some data')
        p = Person(data='some data')
        p.balls.append(b)
        p.balls.append(Ball(data='some data'))
        p.balls.append(Ball(data='some data'))
        p.balls.append(Ball(data='some data'))
        p.favorite = b
        sess = create_session()
        sess.add(b)
        sess.add(p)

        self.assert_sql_execution(
            testing.db,
            sess.flush,
            RegexSQL("^INSERT INTO person", {'data':'some data'}),
            RegexSQL("^INSERT INTO ball", lambda c: {'person_id':p.id, 'data':'some data'}),
            RegexSQL("^INSERT INTO ball", lambda c: {'person_id':p.id, 'data':'some data'}),
            RegexSQL("^INSERT INTO ball", lambda c: {'person_id':p.id, 'data':'some data'}),
            RegexSQL("^INSERT INTO ball", lambda c: {'person_id':p.id, 'data':'some data'}),
            ExactSQL("UPDATE person SET favorite_ball_id=:favorite_ball_id "
                        "WHERE person.id = :person_id",
                        lambda ctx:{'favorite_ball_id':p.favorite.id, 'person_id':p.id}
             ),
        )

        sess.delete(p)

        self.assert_sql_execution(
            testing.db, 
            sess.flush, 
            ExactSQL("UPDATE person SET favorite_ball_id=:favorite_ball_id "
                "WHERE person.id = :person_id",
                lambda ctx: {'person_id': p.id, 'favorite_ball_id': None}),
            ExactSQL("DELETE FROM ball WHERE ball.id = :id", None), # lambda ctx:[{'id': 1L}, {'id': 4L}, {'id': 3L}, {'id': 2L}])
            ExactSQL("DELETE FROM person WHERE person.id = :id", lambda ctx:[{'id': p.id}])
        )
Пример #22
0
    def test_flush(self):
        mapper(A, a, properties={
            'cs':relation(C, primaryjoin=a.c.cid==c.c.id)})

        mapper(B, b, inherits=A, inherit_condition=b.c.id == a.c.id)

        mapper(C, c, properties={
            'arel':relation(A, primaryjoin=a.c.id == c.c.aid)})

        sess = create_session()
        bobj = B()
        sess.add(bobj)
        cobj = C()
        sess.add(cobj)
        sess.flush()
Пример #23
0
    def test_refresh2(self):
        """test a hang condition that was occuring on expire/refresh"""

        s = create_session()
        mapper(Address, addresses)

        mapper(User,
               users,
               properties=dict(addresses=relation(
                   Address, cascade="all, delete-orphan", lazy=False)))

        u = User()
        u.name = 'Justin'
        a = Address(id=10, email_address='lala')
        u.addresses.append(a)

        s.add(u)
        s.flush()
        s.clear()
        u = s.query(User).filter(User.name == 'Justin').one()

        s.expire(u)
        assert u.name == 'Justin'

        s.refresh(u)
Пример #24
0
    def test_onetomany(self):
        mapper(Node,
               nodes,
               properties={
                   'children':
                   relation(Node,
                            backref=sa.orm.backref('parentnode',
                                                   remote_side=nodes.c.name,
                                                   passive_updates=False),
                            passive_updates=False)
               })

        sess = create_session()
        n1 = Node(name='n1')
        n1.children.append(Node(name='n11'))
        n1.children.append(Node(name='n12'))
        n1.children.append(Node(name='n13'))
        sess.add(n1)
        sess.flush()

        n1.name = 'new n1'
        sess.flush()
        eq_(n1.children[1].parent, 'new n1')
        eq_(['new n1', 'new n1', 'new n1'], [
            n.parent for n in sess.query(Node).filter(
                Node.name.in_(['n11', 'n12', 'n13']))
        ])
Пример #25
0
    def test_nested_joins(self):
        # this is testing some subtle column resolution stuff,
        # concerning corresponding_column() being extremely accurate
        # as well as how mapper sets up its column properties

        mapper(Task_Type, task_type)

        tsk_cnt_join = sa.outerjoin(prj, task, task.c.prj_id == prj.c.id)

        j = sa.outerjoin(task, msg, task.c.id == msg.c.task_id)
        jj = sa.select([
            task.c.id.label('task_id'),
            sa.func.count(msg.c.id).label('props_cnt')
        ],
                       from_obj=[j],
                       group_by=[task.c.id]).alias('prop_c_s')
        jjj = sa.join(task, jj, task.c.id == jj.c.task_id)

        mapper(Joined,
               jjj,
               properties=dict(type=relation(Task_Type, lazy=False)))

        session = create_session()

        eq_(
            session.query(Joined).limit(10).offset(0).one(),
            Joined(id=1, title=u'task 1', props_cnt=0))
Пример #26
0
    def test_basic(self):
        mapper(Employee, employees)
        mapper(Department,
               departments,
               properties=dict(employees=relation(
                   Employee, lazy=False, backref='department')))

        d1 = Department(name='One')
        for e in 'Jim', 'Jack', 'John', 'Susan':
            d1.employees.append(Employee(name=e))

        d2 = Department(name='Two')
        for e in 'Joe', 'Bob', 'Mary', 'Wally':
            d2.employees.append(Employee(name=e))

        sess = create_session()
        sess.add_all((d1, d2))
        sess.flush()

        q = (sess.query(Department).join('employees').filter(
            Employee.name.startswith('J')).distinct().order_by(
                [sa.desc(Department.name)]))

        eq_(q.count(), 2)
        assert q[0] is d2
Пример #27
0
    def test_one_to_one_cascade(self):

        mapper(User, users, properties={
            'address':relation(mapper(Address, addresses),uselist = False)
        })
        on_load = self.on_load_tracker(User)
        self.on_load_tracker(Address, on_load)
        sess = create_session()

        u = User()
        u.id = 7
        u.name = "fred"
        a1 = Address()
        a1.email_address='*****@*****.**'
        u.address = a1

        sess.add(u)
        sess.flush()

        eq_(on_load.called, 0)

        sess2 = create_session()
        u2 = sess2.query(User).get(7)
        eq_(on_load.called, 1)
        u2.name = 'fred2'
        u2.address.email_address = '*****@*****.**'
        eq_(on_load.called, 2)

        u3 = sess.merge(u2)
        eq_(on_load.called, 2)
        assert u3 is u
Пример #28
0
    def test_basic(self):
        class A(_fixtures.Base):
            pass
        class B(_fixtures.Base):
            pass

        mapper(A, table_a, properties={
            'bs':relation(B, cascade="all, delete-orphan")
            })
        mapper(B, table_b)

        a1 = A(name='a1', bs=[B(name='b1'), B(name='b2'), B(name='b3')])

        sess = create_session()
        sess.add(a1)
        sess.flush()

        sess.clear()

        eq_(sess.query(A).get(a1.id),
            A(name='a1', bs=[B(name='b1'), B(name='b2'), B(name='b3')]))

        a1 = sess.query(A).get(a1.id)
        assert not class_mapper(B)._is_orphan(
            attributes.instance_state(a1.bs[0]))
        a1.bs[0].foo='b2modified'
        a1.bs[1].foo='b3modified'
        sess.flush()

        sess.clear()
        eq_(sess.query(A).get(a1.id),
            A(name='a1', bs=[B(name='b1'), B(name='b2'), B(name='b3')]))
Пример #29
0
    def test_dontload_with_eager(self):
        """

        This test illustrates that with dont_load=True, we can't just copy the
        committed_state of the merged instance over; since it references
        collection objects which themselves are to be merged.  This
        committed_state would instead need to be piecemeal 'converted' to
        represent the correct objects.  However, at the moment I'd rather not
        support this use case; if you are merging with dont_load=True, you're
        typically dealing with caching and the merged objects shouldnt be
        'dirty'.

        """
        mapper(User, users, properties={
            'addresses':relation(mapper(Address, addresses))
        })
        sess = create_session()
        u = User()
        u.id = 7
        u.name = "fred"
        a1 = Address()
        a1.email_address='*****@*****.**'
        u.addresses.append(a1)

        sess.add(u)
        sess.flush()

        sess2 = create_session()
        u2 = sess2.query(User).options(sa.orm.eagerload('addresses')).get(7)

        sess3 = create_session()
        u3 = sess3.merge(u2, dont_load=True)
        def go():
            sess3.flush()
        self.assert_sql_count(testing.db, go, 0)
Пример #30
0
    def test_is_modified(self):
        s = create_session()

        mapper(User, users, properties={'addresses':relation(Address)})
        mapper(Address, addresses)

        # save user
        u = User(name='fred')
        s.add(u)
        s.flush()
        s.clear()

        user = s.query(User).one()
        assert user not in s.dirty
        assert not s.is_modified(user)
        user.name = 'fred'
        assert user in s.dirty
        assert not s.is_modified(user)
        user.name = 'ed'
        assert user in s.dirty
        assert s.is_modified(user)
        s.flush()
        assert user not in s.dirty
        assert not s.is_modified(user)

        a = Address()
        user.addresses.append(a)
        assert user in s.dirty
        assert s.is_modified(user)
        assert not s.is_modified(user, include_collections=False)
Пример #31
0
    def test_basic(self):
        Session = scoped_session(sa.orm.sessionmaker())

        class CustomQuery(query.Query):
            pass

        class SomeObject(_base.ComparableEntity):
            query = Session.query_property()
        class SomeOtherObject(_base.ComparableEntity):
            query = Session.query_property()
            custom_query = Session.query_property(query_cls=CustomQuery)

        mapper(SomeObject, table1, properties={
            'options':relation(SomeOtherObject)})
        mapper(SomeOtherObject, table2)

        s = SomeObject(id=1, data="hello")
        sso = SomeOtherObject()
        s.options.append(sso)
        Session.add(s)
        Session.commit()
        Session.refresh(sso)
        Session.remove()

        eq_(SomeObject(id=1, data="hello", options=[SomeOtherObject(someid=1)]),
            Session.query(SomeObject).one())
        eq_(SomeObject(id=1, data="hello", options=[SomeOtherObject(someid=1)]),
            SomeObject.query.one())
        eq_(SomeOtherObject(someid=1),
            SomeOtherObject.query.filter(
                SomeOtherObject.someid == sso.someid).one())
        assert isinstance(SomeOtherObject.query, query.Query)
        assert not isinstance(SomeOtherObject.query, CustomQuery)
        assert isinstance(SomeOtherObject.custom_query, query.Query)
Пример #32
0
    def test_class_deferred_cols(self):
        mapper(User, users, properties={
            'name':sa.orm.deferred(users.c.name),
            'addresses':relation(Address, backref="user")
        })
        mapper(Address, addresses, properties={
            'email_address':sa.orm.deferred(addresses.c.email_address)
        })
        sess = create_session()
        u1 = User(name='ed')
        u1.addresses.append(Address(email_address='*****@*****.**'))
        sess.add(u1)
        sess.flush()
        sess.clear()
        u1 = sess.query(User).get(u1.id)
        assert 'name' not in u1.__dict__
        assert 'addresses' not in u1.__dict__

        u2 = pickle.loads(pickle.dumps(u1))
        sess2 = create_session()
        sess2.update(u2)
        self.assertEquals(u2.name, 'ed')
        self.assertEquals(u2, User(name='ed', addresses=[Address(email_address='*****@*****.**')]))

        u2 = pickle.loads(pickle.dumps(u1))
        sess2 = create_session()
        u2 = sess2.merge(u2, dont_load=True)
        self.assertEquals(u2.name, 'ed')
        self.assertEquals(u2, User(name='ed', addresses=[Address(email_address='*****@*****.**')]))
Пример #33
0
    def test_detached_to_persistent_collection(self):
        mapper(User, users, properties={
            'addresses':relation(Address,
                                 backref='user',
                                 collection_class=OrderedSet)})
        mapper(Address, addresses)
        on_load = self.on_load_tracker(User)
        self.on_load_tracker(Address, on_load)

        a = Address(id=1, email_address='fred1')
        u = User(id=7, name='fred', addresses=OrderedSet([
            a,
            Address(id=2, email_address='fred2'),
        ]))
        sess = create_session()
        sess.add(u)
        sess.flush()
        sess.clear()

        u.name='fred jones'
        u.addresses.add(Address(id=3, email_address='fred3'))
        u.addresses.remove(a)

        eq_(on_load.called, 0)
        u = sess.merge(u)
        eq_(on_load.called, 4)
        sess.flush()
        sess.clear()

        eq_(sess.query(User).first(),
            User(id=7, name='fred jones', addresses=OrderedSet([
                Address(id=2, email_address='fred2'),
                Address(id=3, email_address='fred3')])))
Пример #34
0
    def test_compileonattr_rel_backref_a(self):
        m = MetaData()
        t1 = Table('t1', m, Column('id', Integer, primary_key=True),
                   Column('x', Integer))
        t2 = Table('t2', m, Column('id', Integer, primary_key=True),
                   Column('t1_id', Integer, ForeignKey('t1.id')))

        class Base(object):
            def __init__(self, *args, **kwargs):
                pass

        for base in object, Base:

            class A(base):
                pass

            class B(base):
                pass

            mapper(A, t1, properties=dict(bs=relation(B, backref='a')))
            mapper(B, t2)

            b = B()
            assert b.a is None
            a = A()
            b.a = a

            session = create_session()
            session.add(b)
            assert a in session, "base is %s" % base
Пример #35
0
    def test_compileonattr_rel_backref_b(self):
        m = MetaData()
        t1 = Table("t1", m, Column("id", Integer, primary_key=True), Column("x", Integer))
        t2 = Table("t2", m, Column("id", Integer, primary_key=True), Column("t1_id", Integer, ForeignKey("t1.id")))

        class Base(object):
            def __init__(self):
                pass

        class Base_AKW(object):
            def __init__(self, *args, **kwargs):
                pass

        for base in object, Base, Base_AKW:

            class A(base):
                pass

            class B(base):
                pass

            mapper(A, t1)
            mapper(B, t2, properties=dict(a=relation(A, backref="bs")))

            a = A()
            b = B()
            b.a = a

            session = create_session()
            session.add(a)
            assert b in session, "base: %s" % base
Пример #36
0
    def test_expired_eager(self):
        mapper(User, users, properties={
            'addresses':relation(Address, backref='user', lazy=False),
            })
        mapper(Address, addresses)

        sess = create_session()
        u = sess.query(User).get(7)

        sess.expire(u)
        assert 'name' not in u.__dict__
        assert 'addresses' not in u.__dict__

        def go():
            assert u.addresses[0].email_address == '*****@*****.**'
            assert u.name == 'jack'
        # two loads, since relation() + scalar are
        # separate right now on per-attribute load
        self.assert_sql_count(testing.db, go, 2)
        assert 'name' in u.__dict__
        assert 'addresses' in u.__dict__

        sess.expire(u, ['name', 'addresses'])
        assert 'name' not in u.__dict__
        assert 'addresses' not in u.__dict__

        def go():
            sess.query(User).filter_by(id=7).one()
            assert u.addresses[0].email_address == '*****@*****.**'
            assert u.name == 'jack'
        # one load, since relation() + scalar are
        # together when eager load used with Query
        self.assert_sql_count(testing.db, go, 1)
Пример #37
0
    def test_basic(self):
        mapper(Employee, employees)
        mapper(Department, departments, properties=dict(employees=relation(Employee, lazy=False, backref="department")))

        d1 = Department(name="One")
        for e in "Jim", "Jack", "John", "Susan":
            d1.employees.append(Employee(name=e))

        d2 = Department(name="Two")
        for e in "Joe", "Bob", "Mary", "Wally":
            d2.employees.append(Employee(name=e))

        sess = create_session()
        sess.add_all((d1, d2))
        sess.flush()

        q = (
            sess.query(Department)
            .join("employees")
            .filter(Employee.name.startswith("J"))
            .distinct()
            .order_by([sa.desc(Department.name)])
        )

        eq_(q.count(), 2)
        assert q[0] is d2
Пример #38
0
    def test_transient_to_pending_collection(self):
        mapper(User, users, properties={
            'addresses': relation(Address, backref='user',
                                  collection_class=OrderedSet)})
        mapper(Address, addresses)
        on_load = self.on_load_tracker(User)
        self.on_load_tracker(Address, on_load)

        u = User(id=7, name='fred', addresses=OrderedSet([
            Address(id=1, email_address='fred1'),
            Address(id=2, email_address='fred2'),
            ]))
        eq_(on_load.called, 0)

        sess = create_session()
        sess.merge(u)
        eq_(on_load.called, 3)

        merged_users = [e for e in sess if isinstance(e, User)]
        eq_(len(merged_users), 1)
        assert merged_users[0] is not u

        sess.flush()
        sess.clear()

        eq_(sess.query(User).one(),
            User(id=7, name='fred', addresses=OrderedSet([
                Address(id=1, email_address='fred1'),
                Address(id=2, email_address='fred2'),
            ]))
        )
Пример #39
0
    def test_correlated_lazyload(self):
        class User(_base.ComparableEntity):
            pass

        class Stuff(_base.ComparableEntity):
            pass

        mapper(Stuff, stuff)

        stuff_view = sa.select([
            stuff.c.id
        ]).where(stuff.c.user_id == user_t.c.id).correlate(user_t).order_by(
            sa.desc(stuff.c.date)).limit(1)

        mapper(User,
               user_t,
               properties={
                   'stuff':
                   relation(Stuff,
                            primaryjoin=sa.and_(
                                user_t.c.id == stuff.c.user_id,
                                stuff.c.id == (stuff_view.as_scalar())))
               })

        sess = create_session()

        eq_(
            sess.query(User).all(), [
                User(name='user1',
                     stuff=[Stuff(date=datetime.date(2007, 12, 15), id=2)]),
                User(name='user2',
                     stuff=[Stuff(id=4, date=datetime.date(2008, 1, 15))]),
                User(name='user3',
                     stuff=[Stuff(id=5, date=datetime.date(2007, 6, 15))])
            ])
Пример #40
0
    def test_uses_get(self):
        """test that a simple many-to-one lazyload optimizes to use query.get()."""

        for pj in (None, users.c.id == addresses.c.user_id,
                   addresses.c.user_id == users.c.id):
            mapper(Address,
                   addresses,
                   properties=dict(user=relation(
                       mapper(User, users), lazy=True, primaryjoin=pj)))

            sess = create_session()

            # load address
            a1 = sess.query(Address).filter_by(
                email_address="*****@*****.**").one()

            # load user that is attached to the address
            u1 = sess.query(User).get(8)

            def go():
                # lazy load of a1.user should get it from the session
                assert a1.user is u1

            self.assert_sql_count(testing.db, go, 0)
            sa.orm.clear_mappers()
Пример #41
0
    def test_dontload_with_backrefs(self):
        """dontload populates relations in both directions without requiring a load"""
        mapper(User, users, properties={
            'addresses':relation(mapper(Address, addresses), backref='user')
        })

        u = User(id=7, name='fred', addresses=[
            Address(email_address='ad1'),
            Address(email_address='ad2')])
        sess = create_session()
        sess.add(u)
        sess.flush()
        sess.close()
        assert 'user' in u.addresses[1].__dict__

        sess = create_session()
        u2 = sess.merge(u, dont_load=True)
        assert 'user' in u2.addresses[1].__dict__
        eq_(u2.addresses[1].user, User(id=7, name='fred'))

        sess.expire(u2.addresses[1], ['user'])
        assert 'user' not in u2.addresses[1].__dict__
        sess.close()

        sess = create_session()
        u = sess.merge(u2, dont_load=True)
        assert 'user' not in u.addresses[1].__dict__
        eq_(u.addresses[1].user, User(id=7, name='fred'))
Пример #42
0
    def _test_manytomany(self, passive_updates):
        mapper(User,
               users,
               properties={
                   'items':
                   relation(Item,
                            secondary=users_to_items,
                            backref='users',
                            passive_updates=passive_updates)
               })
        mapper(Item, items)

        sess = create_session()
        u1 = User(username='******')
        u2 = User(username='******')
        i1 = Item(itemname='item1')
        i2 = Item(itemname='item2')

        u1.items.append(i1)
        u1.items.append(i2)
        i2.users.append(u2)
        sess.add(u1)
        sess.add(u2)
        sess.flush()

        r = sess.query(Item).all()
        # ComparableEntity can't handle a comparison with the backrefs
        # involved....
        self.assertEquals(Item(itemname='item1'), r[0])
        self.assertEquals(['jack'], [u.username for u in r[0].users])
        self.assertEquals(Item(itemname='item2'), r[1])
        self.assertEquals(['jack', 'fred'], [u.username for u in r[1].users])

        u2.username = '******'

        def go():
            sess.flush()

        go()

        def go():
            sess.flush()

        self.assert_sql_count(testing.db, go, 0)

        sess.clear()
        r = sess.query(Item).all()
        self.assertEquals(Item(itemname='item1'), r[0])
        self.assertEquals(['jack'], [u.username for u in r[0].users])
        self.assertEquals(Item(itemname='item2'), r[1])
        self.assertEquals(['ed', 'jack'],
                          sorted([u.username for u in r[1].users]))

        sess.clear()
        u2 = sess.query(User).get(u2.username)
        u2.username = '******'
        sess.flush()
        r = sess.query(Item).with_parent(u2).all()
        self.assertEquals(Item(itemname='item2'), r[0])
Пример #43
0
    def setup_mappers(self):
        Session = scoped_session(sa.orm.create_session)
        Session.mapper(SomeObject, table1, properties={
            'options':relation(SomeOtherObject)
        })
        Session.mapper(SomeOtherObject, table2)

        self.scoping['Session'] = Session
Пример #44
0
 def test_one_to_many_scalar(self):
     mapper(User,
            users,
            properties=dict(address=relation(
                mapper(Address, addresses), lazy=True, uselist=False)))
     q = create_session().query(User)
     l = q.filter(users.c.id == 7).all()
     assert [User(id=7, address=Address(id=1))] == l
Пример #45
0
 def setup_mappers(self):
     mapper(Parent, parent)
     mapper(Child1, child1, inherits=Parent)
     mapper(Child2,
            child2,
            inherits=Parent,
            properties=dict(child1=relation(
                Child1, primaryjoin=child2.c.child1_id == child1.c.id)))
Пример #46
0
    def test_flush(self):
        mapper(A,
               a,
               properties={'cs': relation(C, primaryjoin=a.c.cid == c.c.id)})

        mapper(B, b, inherits=A, inherit_condition=b.c.id == a.c.id)

        mapper(C,
               c,
               properties={'arel': relation(A, primaryjoin=a.c.id == c.c.aid)})

        sess = create_session()
        bobj = B()
        sess.add(bobj)
        cobj = C()
        sess.add(cobj)
        sess.flush()
Пример #47
0
        class Address(Base):
            __tablename__ = 'addresses'

            id = Column('id', Integer, primary_key=True)
            email = Column('email', String(50))
            user_id = Column('user_id', Integer, ForeignKey('users.id'))
            user = relation("User", primaryjoin=user_id == User.id,
                            backref="addresses")
Пример #48
0
 class User(Base, ComparableEntity):
     __tablename__ = 'users'
     id = Column(Integer, primary_key=True)
     name = Column(String(50))
     addresses = relation("Address", order_by=Address.email, 
         foreign_keys=Address.user_id, 
         remote_side=Address.user_id,
         )
Пример #49
0
 class User(Base, ComparableEntity):
     __tablename__ = 'users'
     id = Column(Integer, primary_key=True)
     name = Column(String(50))
     addresses = relation("Address", 
         primaryjoin="User.id==Address.user_id", 
         backref="user"
         )
Пример #50
0
    def _test_bidirectional(self, passive_updates):
        mapper(User, users)
        mapper(Address,
               addresses,
               properties={
                   'user':
                   relation(User,
                            passive_updates=passive_updates,
                            backref='addresses')
               })

        sess = create_session()
        a1 = Address(email='jack1')
        a2 = Address(email='jack2')

        u1 = User(username='******', fullname='jack')
        a1.user = u1
        a2.user = u1
        sess.add(a1)
        sess.add(a2)
        sess.flush()

        u1.username = '******'
        (ad1, ad2) = sess.query(Address).all()
        self.assertEquals([Address(username='******'),
                           Address(username='******')], [ad1, ad2])

        def go():
            sess.flush()

        if passive_updates:
            self.assert_sql_count(testing.db, go, 1)
        else:
            self.assert_sql_count(testing.db, go, 3)
        self.assertEquals([Address(username='******'),
                           Address(username='******')], [ad1, ad2])
        sess.clear()
        self.assertEquals([Address(username='******'),
                           Address(username='******')],
                          sess.query(Address).all())

        u1 = sess.query(User).get('ed')
        assert len(u1.addresses) == 2  # load addresses
        u1.username = '******'
        print "--------------------------------"

        def go():
            sess.flush()

        # check that the passive_updates is on on the other side
        if passive_updates:
            self.assert_sql_count(testing.db, go, 1)
        else:
            self.assert_sql_count(testing.db, go, 3)
        sess.clear()
        self.assertEquals([Address(username='******'),
                           Address(username='******')],
                          sess.query(Address).all())
Пример #51
0
    def test_double(self):
        """test 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.add(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'
                }])
            })
Пример #52
0
 def test_cascades_dont_autoflush(self):
     sess = create_session(autoflush=True)
     m = mapper(User, users, properties={
         'addresses':relation(mapper(Address, addresses),backref='user')})
     user = User(id=8, name='fred', addresses=[Address(email_address='user')])
     merged_user = sess.merge(user)
     assert merged_user in sess.new
     sess.flush()
     assert merged_user not in sess.new
Пример #53
0
    def setup_mappers(self):
        items, item_keywords, keywords = self.tables.get_all(
            'items', 'item_keywords', 'keywords')

        mapper(Keyword, keywords)
        mapper(
            KeywordAssociation,
            item_keywords,
            properties={'keyword': relation(Keyword, lazy=False)},
            primary_key=[item_keywords.c.item_id, item_keywords.c.keyword_id],
            order_by=[item_keywords.c.data])

        mapper(Item,
               items,
               properties={
                   'keywords':
                   relation(KeywordAssociation, cascade="all, delete-orphan")
               })
Пример #54
0
        class User(Base, ComparableEntity):
            __tablename__ = 'users'

            id = Column('id', Integer, primary_key=True)
            name = Column('name', String(50))
            adr_count = sa.orm.column_property(
                sa.select([sa.func.count(Address.id)], Address.user_id == id).
                as_scalar())
            addresses = relation(Address)
Пример #55
0
 def setup_mappers(self):
     mapper(TT,
            item,
            properties={
                'children':
                relation(TT,
                         remote_side=[item.c.parent_uuid],
                         backref=backref('parent',
                                         remote_side=[item.c.uuid]))
            })
Пример #56
0
    def _test_onetomany(self, passive_updates):
        mapper(User,
               users,
               properties={
                   'addresses': relation(Address,
                                         passive_updates=passive_updates)
               })
        mapper(Address, addresses)

        sess = create_session()
        u1 = User(username='******', fullname='jack')
        u1.addresses.append(Address(email='jack1'))
        u1.addresses.append(Address(email='jack2'))
        sess.add(u1)
        sess.flush()

        assert sess.query(Address).get('jack1') is u1.addresses[0]

        u1.username = '******'
        sess.flush()
        assert u1.addresses[0].username == 'ed'

        sess.clear()
        self.assertEquals([Address(username='******'),
                           Address(username='******')],
                          sess.query(Address).all())

        u1 = sess.query(User).get('ed')
        u1.username = '******'

        def go():
            sess.flush()

        if not passive_updates:
            self.assert_sql_count(
                testing.db, go, 4
            )  # test passive_updates=False; load addresses, update user, update 2 addresses
        else:
            self.assert_sql_count(testing.db, go,
                                  1)  # test passive_updates=True; update user
        sess.clear()
        assert User(username='******',
                    addresses=[
                        Address(username='******'),
                        Address(username='******')
                    ]) == sess.query(User).get('jack')

        u1 = sess.query(User).get('jack')
        u1.addresses = []
        u1.username = '******'
        sess.flush()
        sess.clear()
        assert sess.query(Address).get('jack1').username is None
        u1 = sess.query(User).get('fred')
        self.assertEquals(User(username='******', fullname='jack'), u1)
Пример #57
0
    def setup_mappers(self):
        mapper(Account, accounts)

        mapper(Transaction, transactions)

        mapper(Entry,
               entries,
               properties=dict(account=relation(
                   Account,
                   uselist=False,
                   backref=backref('entries',
                                   lazy=True,
                                   order_by=entries.c.entry_id)),
                               transaction=relation(
                                   Transaction,
                                   uselist=False,
                                   backref=backref(
                                       'entries',
                                       lazy=False,
                                       order_by=entries.c.entry_id))))
Пример #58
0
 def test_error(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')
            })
     self.assertRaisesMessage(sa.exc.ArgumentError,
                              "Error creating backref",
                              sa.orm.compile_mappers)
Пример #59
0
    def test_save_update_delete(self):

        s = create_session()
        mapper(User, users, properties={
            'addresses':relation(Address, cascade="all, delete")
        })
        mapper(Address, addresses)

        user = User(name='u1')

        self.assertRaisesMessage(sa.exc.InvalidRequestError, "is not persisted", s.update, user)
        self.assertRaisesMessage(sa.exc.InvalidRequestError, "is not persisted", s.delete, user)

        s.add(user)
        s.flush()
        user = s.query(User).one()
        s.expunge(user)
        assert user not in s

        # modify outside of session, assert changes remain/get saved
        user.name = "fred"
        s.update(user)
        assert user in s
        assert user in s.dirty
        s.flush()
        s.clear()
        assert s.query(User).count() == 1
        user = s.query(User).one()
        assert user.name == 'fred'

        # ensure its not dirty if no changes occur
        s.clear()
        assert user not in s
        s.update(user)
        assert user in s
        assert user not in s.dirty

        self.assertRaisesMessage(sa.exc.InvalidRequestError, "is already persistent", s.save, user)

        s2 = create_session()
        self.assertRaisesMessage(sa.exc.InvalidRequestError, "is already attached to session", s2.delete, user)

        u2 = s2.query(User).get(user.id)
        self.assertRaisesMessage(sa.exc.InvalidRequestError, "another instance with key", s.delete, u2)

        s.expire(user)
        s.expunge(user)
        assert user not in s
        s.delete(user)
        assert user in s
        
        s.flush()
        assert user not in s
        assert s.query(User).count() == 0
Пример #60
0
    def testsingle(self):
        mapper(C1,
               t1,
               properties={
                   'c1s':
                   relation(C1, cascade="all"),
                   'parent':
                   relation(C1,
                            primaryjoin=t1.c.parent_c1 == t1.c.c1,
                            remote_side=t1.c.c1,
                            lazy=True,
                            uselist=False)
               })
        a = C1('head c1')
        a.c1s.append(C1('another c1'))

        sess = create_session()
        sess.add(a)
        sess.flush()
        sess.delete(a)
        sess.flush()