Beispiel #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
Beispiel #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
Beispiel #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
Beispiel #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
Beispiel #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'}])})
Beispiel #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)
Beispiel #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")
Beispiel #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'}])
            })
Beispiel #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")))
Beispiel #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)})
Beispiel #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)),
     )
Beispiel #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)
Beispiel #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)
Beispiel #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))})
Beispiel #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)
     })
Beispiel #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)
Beispiel #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)
Beispiel #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)))),
Beispiel #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))))
Beispiel #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")
        })
Beispiel #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}])
        )
Beispiel #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()
Beispiel #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)
Beispiel #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']))
        ])
Beispiel #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))
Beispiel #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
Beispiel #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
Beispiel #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')]))
Beispiel #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)
Beispiel #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)
Beispiel #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)
Beispiel #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='*****@*****.**')]))
Beispiel #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')])))
Beispiel #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
Beispiel #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
Beispiel #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)
Beispiel #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
Beispiel #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'),
            ]))
        )
Beispiel #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))])
            ])
Beispiel #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()
Beispiel #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'))
Beispiel #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])
Beispiel #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
Beispiel #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
Beispiel #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)))
Beispiel #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()
Beispiel #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")
Beispiel #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,
         )
Beispiel #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"
         )
Beispiel #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())
Beispiel #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'
                }])
            })
Beispiel #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
Beispiel #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")
               })
Beispiel #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)
Beispiel #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]))
            })
Beispiel #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)
Beispiel #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))))
Beispiel #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)
Beispiel #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
Beispiel #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()