Exemple #1
0
    def test_one_to_many_save(self):
        Node, nodes = self.classes.Node, self.tables.nodes

        mapper(Node, nodes, properties={'children': relationship(Node)})
        sess = create_session()

        n2, n3 = Node(data='n2'), Node(data='n3')
        n1 = Node(data='n1', children=[n2, n3])

        sess.add(n1)

        self.assert_sql_execution(
            testing.db, sess.flush,
            CompiledSQL(
                "INSERT INTO nodes (parent_id, data) VALUES "
                "(:parent_id, :data)", {
                    'parent_id': None,
                    'data': 'n1'
                }),
            AllOf(
                CompiledSQL(
                    "INSERT INTO nodes (parent_id, data) VALUES "
                    "(:parent_id, :data)", lambda ctx: {
                        'parent_id': n1.id,
                        'data': 'n2'
                    }),
                CompiledSQL(
                    "INSERT INTO nodes (parent_id, data) VALUES "
                    "(:parent_id, :data)", lambda ctx: {
                        'parent_id': n1.id,
                        'data': 'n3'
                    }),
            ))
Exemple #2
0
    def test_one_to_many_delete_parent(self):
        Node, nodes = self.classes.Node, self.tables.nodes

        mapper(Node, nodes, properties={'children': relationship(Node)})
        sess = create_session()

        n2, n3 = Node(data='n2', children=[]), Node(data='n3', children=[])
        n1 = Node(data='n1', children=[n2, n3])

        sess.add(n1)
        sess.flush()

        sess.delete(n1)
        self.assert_sql_execution(
            testing.db, sess.flush,
            AllOf(
                CompiledSQL(
                    "UPDATE nodes SET parent_id=:parent_id "
                    "WHERE nodes.id = :nodes_id", lambda ctx: {
                        'nodes_id': n3.id,
                        'parent_id': None
                    }),
                CompiledSQL(
                    "UPDATE nodes SET parent_id=:parent_id "
                    "WHERE nodes.id = :nodes_id", lambda ctx: {
                        'nodes_id': n2.id,
                        'parent_id': None
                    }),
            ),
            CompiledSQL("DELETE FROM nodes WHERE nodes.id = :id",
                        lambda ctx: {'id': n1.id}))
Exemple #3
0
    def test_one_to_many_delete_all(self):
        users, Address, addresses, User = (self.tables.users,
                                           self.classes.Address,
                                           self.tables.addresses,
                                           self.classes.User)

        mapper(User, users, properties={
            'addresses': relationship(Address),
        })
        mapper(Address, addresses)
        sess = create_session()
        a1, a2 = Address(email_address='a1'), Address(email_address='a2')
        u1 = User(name='u1', addresses=[a1, a2])
        sess.add(u1)
        sess.flush()

        sess.delete(u1)
        sess.delete(a1)
        sess.delete(a2)
        self.assert_sql_execution(
            testing.db,
            sess.flush,
            CompiledSQL("DELETE FROM addresses WHERE addresses.id = :id",
                        [{
                            'id': a1.id
                        }, {
                            'id': a2.id
                        }]),
            CompiledSQL("DELETE FROM users WHERE users.id = :id",
                        {'id': u1.id}),
        )
Exemple #4
0
    def test_many_to_one_delete_all(self):
        Node, nodes = self.classes.Node, self.tables.nodes

        mapper(
            Node,
            nodes,
            properties={'parent': relationship(Node, remote_side=nodes.c.id)})
        sess = create_session()

        n1 = Node(data='n1')
        n2, n3 = Node(data='n2', parent=n1), Node(data='n3', parent=n1)

        sess.add_all([n2, n3])
        sess.flush()

        sess.delete(n1)
        sess.delete(n2)
        sess.delete(n3)
        self.assert_sql_execution(
            testing.db, sess.flush,
            CompiledSQL("DELETE FROM nodes WHERE nodes.id = :id",
                        lambda ctx: [{
                            'id': n2.id
                        }, {
                            'id': n3.id
                        }]),
            CompiledSQL("DELETE FROM nodes WHERE nodes.id = :id",
                        lambda ctx: {'id': n1.id}))
Exemple #5
0
    def test_one_to_many_save(self):
        users, Address, addresses, User = (self.tables.users,
                                           self.classes.Address,
                                           self.tables.addresses,
                                           self.classes.User)

        mapper(User, users, properties={
            'addresses': relationship(Address),
        })
        mapper(Address, addresses)
        sess = create_session()

        a1, a2 = Address(email_address='a1'), Address(email_address='a2')
        u1 = User(name='u1', addresses=[a1, a2])
        sess.add(u1)

        self.assert_sql_execution(
            testing.db,
            sess.flush,
            CompiledSQL("INSERT INTO users (name) VALUES (:name)",
                        {'name': 'u1'}),
            CompiledSQL(
                "INSERT INTO addresses (user_id, email_address) "
                "VALUES (:user_id, :email_address)", lambda ctx: {
                    'email_address': 'a1',
                    'user_id': u1.id
                }),
            CompiledSQL(
                "INSERT INTO addresses (user_id, email_address) "
                "VALUES (:user_id, :email_address)", lambda ctx: {
                    'email_address': 'a2',
                    'user_id': u1.id
                }),
        )
Exemple #6
0
    def test_many_to_one_delete_childonly_unloaded_expired(self):
        users, Address, addresses, User = (self.tables.users,
                                           self.classes.Address,
                                           self.tables.addresses,
                                           self.classes.User)

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

        parent = User(name='p1')
        c1, c2 = Address(email_address='c1', parent=parent), \
                    Address(email_address='c2', parent=parent)

        session = Session()
        session.add_all([c1, c2])
        session.add(parent)

        session.flush()

        pid = parent.id
        c1id = c1.id
        c2id = c2.id

        session.expire(parent)
        session.expire(c1)
        session.expire(c2)

        session.delete(c1)
        session.delete(c2)

        self.assert_sql_execution(
            testing.db,
            session.flush,
            AllOf(
                # the parent User is expired, so it gets loaded here.
                CompiledSQL(
                    "SELECT addresses.id AS addresses_id, addresses.user_id AS "
                    "addresses_user_id, addresses.email_address AS "
                    "addresses_email_address FROM addresses WHERE addresses.id = "
                    ":param_1", lambda ctx: {'param_1': c1id}),
                CompiledSQL(
                    "SELECT addresses.id AS addresses_id, addresses.user_id AS "
                    "addresses_user_id, addresses.email_address AS "
                    "addresses_email_address FROM addresses WHERE addresses.id = "
                    ":param_1", lambda ctx: {'param_1': c2id}),
            ),
            CompiledSQL("DELETE FROM addresses WHERE addresses.id = :id",
                        lambda ctx: [{
                            'id': c1id
                        }, {
                            'id': c2id
                        }]),
        )
Exemple #7
0
    def test_many_to_many(self):
        keywords, items, item_keywords, Keyword, Item = (
            self.tables.keywords, self.tables.items, self.tables.item_keywords,
            self.classes.Keyword, self.classes.Item)

        mapper(Item,
               items,
               properties={
                   'keywords': relationship(Keyword, secondary=item_keywords)
               })
        mapper(Keyword, keywords)

        sess = create_session()
        k1 = Keyword(name='k1')
        i1 = Item(description='i1', keywords=[k1])
        sess.add(i1)
        self.assert_sql_execution(
            testing.db, sess.flush,
            AllOf(
                CompiledSQL("INSERT INTO keywords (name) VALUES (:name)",
                            {'name': 'k1'}),
                CompiledSQL(
                    "INSERT INTO items (description) VALUES (:description)",
                    {'description': 'i1'}),
            ),
            CompiledSQL(
                "INSERT INTO item_keywords (item_id, keyword_id) "
                "VALUES (:item_id, :keyword_id)", lambda ctx: {
                    'item_id': i1.id,
                    'keyword_id': k1.id
                }))

        # test that keywords collection isn't loaded
        sess.expire(i1, ['keywords'])
        i1.description = 'i2'
        self.assert_sql_execution(
            testing.db, sess.flush,
            CompiledSQL(
                "UPDATE items SET description=:description "
                "WHERE items.id = :items_id", lambda ctx: {
                    'description': 'i2',
                    'items_id': i1.id
                }))
Exemple #8
0
    def test_natural_ordering(self):
        """test that unconnected items take relationship() into account regardless."""

        users, Address, addresses, User = (self.tables.users,
                                           self.classes.Address,
                                           self.tables.addresses,
                                           self.classes.User)

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

        sess = create_session()

        u1 = User(id=1, name='u1')
        a1 = Address(id=1, user_id=1, email_address='a2')

        sess.add_all([u1, a1])
        self.assert_sql_execution(
            testing.db, sess.flush,
            CompiledSQL("INSERT INTO users (id, name) VALUES (:id, :name)", {
                'id': 1,
                'name': 'u1'
            }),
            CompiledSQL(
                "INSERT INTO addresses (id, user_id, email_address) "
                "VALUES (:id, :user_id, :email_address)", {
                    'email_address': 'a2',
                    'user_id': 1,
                    'id': 1
                }))

        sess.delete(u1)
        sess.delete(a1)
        self.assert_sql_execution(
            testing.db, sess.flush,
            CompiledSQL("DELETE FROM addresses WHERE addresses.id = :id",
                        [{
                            'id': 1
                        }]),
            CompiledSQL("DELETE FROM users WHERE users.id = :id", [{
                'id': 1
            }]))
Exemple #9
0
    def test_many_to_one_delete_target(self):
        users, Address, addresses, User = (self.tables.users,
                                           self.classes.Address,
                                           self.tables.addresses,
                                           self.classes.User)

        mapper(User, users)
        mapper(Address, addresses, properties={'user': relationship(User)})
        sess = create_session()

        u1 = User(name='u1')
        a1, a2 = Address(email_address='a1', user=u1), \
                    Address(email_address='a2', user=u1)
        sess.add_all([a1, a2])
        sess.flush()

        sess.delete(u1)
        a1.user = a2.user = None
        self.assert_sql_execution(
            testing.db,
            sess.flush,
            CompiledSQL(
                "UPDATE addresses SET user_id=:user_id WHERE "
                "addresses.id = :addresses_id",
                lambda ctx: [{
                    u'addresses_id': a1.id,
                    'user_id': None
                }]),
            CompiledSQL(
                "UPDATE addresses SET user_id=:user_id WHERE "
                "addresses.id = :addresses_id",
                lambda ctx: [{
                    u'addresses_id': a2.id,
                    'user_id': None
                }]),
            CompiledSQL("DELETE FROM users WHERE users.id = :id",
                        {'id': u1.id}),
        )
Exemple #10
0
    def test_rowswitch_doesntfire(self):
        User, Address, users, addresses = (self.classes.User,
                                           self.classes.Address,
                                           self.tables.users,
                                           self.tables.addresses)

        mapper(User, users)
        mapper(Address,
               addresses,
               properties={'user': relationship(User, passive_updates=True)})

        sess = create_session()
        u1 = User(username='******')
        a1 = Address(user=u1, email='ed@host1')

        sess.add(u1)
        sess.add(a1)
        sess.flush()

        sess.delete(u1)
        sess.delete(a1)

        u2 = User(username='******')
        a2 = Address(user=u2, email='ed@host1', etc='foo')
        sess.add(u2)
        sess.add(a2)

        from test.lib.assertsql import CompiledSQL

        # test that the primary key columns of addresses are not
        # being updated as well, since this is a row switch.
        self.assert_sql_execution(
            testing.db,
            sess.flush,
            CompiledSQL(
                "UPDATE addresses SET etc=:etc WHERE "
                "addresses.username = :addresses_username AND"
                " addresses.email = :addresses_email", {
                    'etc': 'foo',
                    'addresses_username': '******',
                    'addresses_email': 'ed@host1'
                }),
        )
Exemple #11
0
    def test_many_to_one_set_null_unloaded(self):
        Node, nodes = self.classes.Node, self.tables.nodes

        mapper(
            Node,
            nodes,
            properties={'parent': relationship(Node, remote_side=nodes.c.id)})
        sess = create_session()
        n1 = Node(data='n1')
        n2 = Node(data='n2', parent=n1)
        sess.add_all([n1, n2])
        sess.flush()
        sess.close()

        n2 = sess.query(Node).filter_by(data='n2').one()
        n2.parent = None
        self.assert_sql_execution(
            testing.db, sess.flush,
            CompiledSQL(
                "UPDATE nodes SET parent_id=:parent_id WHERE "
                "nodes.id = :nodes_id", lambda ctx: {
                    "parent_id": None,
                    "nodes_id": n2.id
                }))
Exemple #12
0
    def test_natural_selfref(self):
        """test that unconnected items take relationship() into account regardless."""

        Node, nodes = self.classes.Node, self.tables.nodes

        mapper(Node, nodes, properties={'children': relationship(Node)})

        sess = create_session()

        n1 = Node(id=1)
        n2 = Node(id=2, parent_id=1)
        n3 = Node(id=3, parent_id=2)

        # insert order is determined from add order since they
        # are the same class
        sess.add_all([n1, n2, n3])

        self.assert_sql_execution(
            testing.db,
            sess.flush,
            CompiledSQL(
                "INSERT INTO nodes (id, parent_id, data) VALUES "
                "(:id, :parent_id, :data)", [{
                    'parent_id': None,
                    'data': None,
                    'id': 1
                }, {
                    'parent_id': 1,
                    'data': None,
                    'id': 2
                }, {
                    'parent_id': 2,
                    'data': None,
                    'id': 3
                }]),
        )
Exemple #13
0
    def test_one(self):
        """Post_update only fires off when needed.

        This test case used to produce many superfluous update statements,
        particularly upon delete

        """

        node, Node = self.tables.node, self.classes.Node

        mapper(
            Node,
            node,
            properties={
                'children':
                relationship(Node,
                             primaryjoin=node.c.id == node.c.parent_id,
                             cascade="all",
                             backref=backref("parent", remote_side=node.c.id)),
                'prev_sibling':
                relationship(Node,
                             primaryjoin=node.c.prev_sibling_id == node.c.id,
                             remote_side=node.c.id,
                             uselist=False),
                'next_sibling':
                relationship(Node,
                             primaryjoin=node.c.next_sibling_id == node.c.id,
                             remote_side=node.c.id,
                             uselist=False,
                             post_update=True)
            })

        session = create_session()

        def append_child(parent, child):
            if parent.children:
                parent.children[-1].next_sibling = child
                child.prev_sibling = parent.children[-1]
            parent.children.append(child)

        def remove_child(parent, child):
            child.parent = None
            node = child.next_sibling
            node.prev_sibling = child.prev_sibling
            child.prev_sibling.next_sibling = node
            session.delete(child)

        root = Node('root')

        about = Node('about')
        cats = Node('cats')
        stories = Node('stories')
        bruce = Node('bruce')

        append_child(root, about)
        assert (about.prev_sibling is None)
        append_child(root, cats)
        assert (cats.prev_sibling is about)
        assert (cats.next_sibling is None)
        assert (about.next_sibling is cats)
        assert (about.prev_sibling is None)
        append_child(root, stories)
        append_child(root, bruce)
        session.add(root)
        session.flush()

        remove_child(root, cats)

        # pre-trigger lazy loader on 'cats' to make the test easier
        cats.children
        self.assert_sql_execution(
            testing.db, session.flush,
            AllOf(
                CompiledSQL(
                    "UPDATE node SET prev_sibling_id=:prev_sibling_id "
                    "WHERE node.id = :node_id", lambda ctx: {
                        'prev_sibling_id': about.id,
                        'node_id': stories.id
                    }),
                CompiledSQL(
                    "UPDATE node SET next_sibling_id=:next_sibling_id "
                    "WHERE node.id = :node_id", lambda ctx: {
                        'next_sibling_id': stories.id,
                        'node_id': about.id
                    }),
                CompiledSQL(
                    "UPDATE node SET next_sibling_id=:next_sibling_id "
                    "WHERE node.id = :node_id", lambda ctx: {
                        'next_sibling_id': None,
                        'node_id': cats.id
                    }),
            ),
            CompiledSQL("DELETE FROM node WHERE node.id = :id",
                        lambda ctx: [{
                            'id': cats.id
                        }]))

        session.delete(root)

        self.assert_sql_execution(
            testing.db,
            session.flush,
            CompiledSQL(
                "UPDATE node SET next_sibling_id=:next_sibling_id "
                "WHERE node.id = :node_id",
                lambda ctx: [{
                    'node_id': about.id,
                    'next_sibling_id': None
                }, {
                    'node_id': stories.id,
                    'next_sibling_id': None
                }]),
            AllOf(
                CompiledSQL("DELETE FROM node WHERE node.id = :id",
                            lambda ctx: {'id': about.id}),
                CompiledSQL("DELETE FROM node WHERE node.id = :id",
                            lambda ctx: {'id': stories.id}),
                CompiledSQL("DELETE FROM node WHERE node.id = :id",
                            lambda ctx: {'id': bruce.id}),
            ),
            CompiledSQL("DELETE FROM node WHERE node.id = :id",
                        lambda ctx: {'id': root.id}),
        )
        about = Node('about')
        cats = Node('cats')
        about.next_sibling = cats
        cats.prev_sibling = about
        session.add(about)
        session.flush()
        session.delete(about)
        cats.prev_sibling = None
        session.flush()
Exemple #14
0
    def test_many_to_many_one(self):
        nodes, node_to_nodes = self.tables.nodes, self.tables.node_to_nodes

        class Node(fixtures.ComparableEntity):
            pass

        mapper(
            Node,
            nodes,
            properties={
                'children':
                relationship(
                    Node,
                    secondary=node_to_nodes,
                    primaryjoin=nodes.c.id == node_to_nodes.c.left_node_id,
                    secondaryjoin=nodes.c.id == node_to_nodes.c.right_node_id,
                    backref='parents'),
                'favorite':
                relationship(Node, remote_side=nodes.c.id)
            })

        sess = create_session()
        n1 = Node(data='n1')
        n2 = Node(data='n2')
        n3 = Node(data='n3')
        n4 = Node(data='n4')
        n5 = Node(data='n5')

        n4.favorite = n3
        n1.favorite = n5
        n5.favorite = n2

        n1.children = [n2, n3, n4]
        n2.children = [n3, n5]
        n3.children = [n5, n4]

        sess.add_all([n1, n2, n3, n4, n5])

        # can't really assert the SQL on this easily
        # since there's too many ways to insert the rows.
        # so check the end result
        sess.flush()
        eq_(
            sess.query(node_to_nodes.c.left_node_id,
                            node_to_nodes.c.right_node_id).\
                    order_by(node_to_nodes.c.left_node_id,
                            node_to_nodes.c.right_node_id).\
                    all(),
            sorted([
                    (n1.id, n2.id), (n1.id, n3.id), (n1.id, n4.id),
                    (n2.id, n3.id), (n2.id, n5.id),
                    (n3.id, n5.id), (n3.id, n4.id)
                ])
        )

        sess.delete(n1)

        self.assert_sql_execution(
            testing.db,
            sess.flush,
            # this is n1.parents firing off, as it should, since
            # passive_deletes is False for n1.parents
            CompiledSQL(
                "SELECT nodes.id AS nodes_id, nodes.data AS nodes_data, "
                "nodes.favorite_node_id AS nodes_favorite_node_id FROM "
                "nodes, node_to_nodes WHERE :param_1 = "
                "node_to_nodes.right_node_id AND nodes.id = "
                "node_to_nodes.left_node_id",
                lambda ctx: {u'param_1': n1.id},
            ),
            CompiledSQL(
                "DELETE FROM node_to_nodes WHERE "
                "node_to_nodes.left_node_id = :left_node_id AND "
                "node_to_nodes.right_node_id = :right_node_id",
                lambda ctx: [{
                    'right_node_id': n2.id,
                    'left_node_id': n1.id
                }, {
                    'right_node_id': n3.id,
                    'left_node_id': n1.id
                }, {
                    'right_node_id': n4.id,
                    'left_node_id': n1.id
                }]),
            CompiledSQL("DELETE FROM nodes WHERE nodes.id = :id",
                        lambda ctx: {'id': n1.id}),
        )

        for n in [n2, n3, n4, n5]:
            sess.delete(n)

        # load these collections
        # outside of the flush() below
        n4.children
        n5.children

        self.assert_sql_execution(
            testing.db,
            sess.flush,
            CompiledSQL(
                "DELETE FROM node_to_nodes WHERE node_to_nodes.left_node_id "
                "= :left_node_id AND node_to_nodes.right_node_id = "
                ":right_node_id", lambda ctx: [{
                    'right_node_id': n5.id,
                    'left_node_id': n3.id
                }, {
                    'right_node_id': n4.id,
                    'left_node_id': n3.id
                }, {
                    'right_node_id': n3.id,
                    'left_node_id': n2.id
                }, {
                    'right_node_id': n5.id,
                    'left_node_id': n2.id
                }]),
            CompiledSQL("DELETE FROM nodes WHERE nodes.id = :id",
                        lambda ctx: [{
                            'id': n4.id
                        }, {
                            'id': n5.id
                        }]),
            CompiledSQL("DELETE FROM nodes WHERE nodes.id = :id",
                        lambda ctx: [{
                            'id': n2.id
                        }, {
                            'id': n3.id
                        }]),
        )
Exemple #15
0
    def test_batch_interaction(self):
        """test batching groups same-structured, primary
        key present statements together.

        """

        t = self.tables.t

        class T(fixtures.ComparableEntity):
            pass

        mapper(T, t)
        sess = Session()
        sess.add_all([
            T(data='t1'),
            T(data='t2'),
            T(id=3, data='t3'),
            T(id=4, data='t4'),
            T(id=5, data='t5'),
            T(id=6, data=func.lower('t6')),
            T(id=7, data='t7'),
            T(id=8, data='t8'),
            T(id=9, data='t9', def_='def2'),
            T(id=10, data='t10', def_='def3'),
            T(id=11, data='t11'),
        ])
        self.assert_sql_execution(
            testing.db,
            sess.flush,
            CompiledSQL("INSERT INTO t (data) VALUES (:data)", {'data': 't1'}),
            CompiledSQL("INSERT INTO t (data) VALUES (:data)", {'data': 't2'}),
            CompiledSQL("INSERT INTO t (id, data) VALUES (:id, :data)",
                        [{
                            'data': 't3',
                            'id': 3
                        }, {
                            'data': 't4',
                            'id': 4
                        }, {
                            'data': 't5',
                            'id': 5
                        }]),
            CompiledSQL(
                "INSERT INTO t (id, data) VALUES (:id, lower(:lower_1))", {
                    'lower_1': 't6',
                    'id': 6
                }),
            CompiledSQL("INSERT INTO t (id, data) VALUES (:id, :data)",
                        [{
                            'data': 't7',
                            'id': 7
                        }, {
                            'data': 't8',
                            'id': 8
                        }]),
            CompiledSQL(
                "INSERT INTO t (id, data, def_) VALUES (:id, :data, :def_)",
                [{
                    'data': 't9',
                    'id': 9,
                    'def_': 'def2'
                }, {
                    'data': 't10',
                    'id': 10,
                    'def_': 'def3'
                }]),
            CompiledSQL("INSERT INTO t (id, data) VALUES (:id, :data)", {
                'data': 't11',
                'id': 11
            }),
        )
Exemple #16
0
    def test_post_update_o2m(self):
        """A cycle between two rows, with a post_update on the one-to-many"""

        person, ball, Ball, Person = (self.tables.person, self.tables.ball,
                                      self.classes.Ball, self.classes.Person)

        mapper(Ball, ball)
        mapper(Person,
               person,
               properties=dict(
                   balls=relationship(
                       Ball,
                       primaryjoin=ball.c.person_id == person.c.id,
                       remote_side=ball.c.person_id,
                       cascade="all, delete-orphan",
                       post_update=True,
                       backref='person'),
                   favorite=relationship(
                       Ball,
                       primaryjoin=person.c.favorite_ball_id == ball.c.id,
                       remote_side=person.c.favorite_ball_id)))

        b = Ball(data='some data')
        p = Person(data='some data')
        p.balls.append(b)
        b2 = Ball(data='some data')
        p.balls.append(b2)
        b3 = Ball(data='some data')
        p.balls.append(b3)
        b4 = Ball(data='some data')
        p.balls.append(b4)
        p.favorite = b
        sess = create_session()
        sess.add_all((b, p, b2, b3, b4))

        self.assert_sql_execution(
            testing.db,
            sess.flush,
            CompiledSQL(
                "INSERT INTO ball (person_id, data) "
                "VALUES (:person_id, :data)", {
                    'person_id': None,
                    'data': 'some data'
                }),
            CompiledSQL(
                "INSERT INTO ball (person_id, data) "
                "VALUES (:person_id, :data)", {
                    'person_id': None,
                    'data': 'some data'
                }),
            CompiledSQL(
                "INSERT INTO ball (person_id, data) "
                "VALUES (:person_id, :data)", {
                    'person_id': None,
                    'data': 'some data'
                }),
            CompiledSQL(
                "INSERT INTO ball (person_id, data) "
                "VALUES (:person_id, :data)", {
                    'person_id': None,
                    'data': 'some data'
                }),
            CompiledSQL(
                "INSERT INTO person (favorite_ball_id, data) "
                "VALUES (:favorite_ball_id, :data)", lambda ctx: {
                    'favorite_ball_id': b.id,
                    'data': 'some data'
                }),
            CompiledSQL(
                "UPDATE ball SET person_id=:person_id "
                "WHERE ball.id = :ball_id", lambda ctx: [{
                    'person_id': p.id,
                    'ball_id': b.id
                }, {
                    'person_id': p.id,
                    'ball_id': b2.id
                }, {
                    'person_id': p.id,
                    'ball_id': b3.id
                }, {
                    'person_id': p.id,
                    'ball_id': b4.id
                }]),
        )

        sess.delete(p)

        self.assert_sql_execution(
            testing.db, sess.flush,
            CompiledSQL(
                "UPDATE ball SET person_id=:person_id "
                "WHERE ball.id = :ball_id", lambda ctx: [{
                    'person_id': None,
                    'ball_id': b.id
                }, {
                    'person_id': None,
                    'ball_id': b2.id
                }, {
                    'person_id': None,
                    'ball_id': b3.id
                }, {
                    'person_id': None,
                    'ball_id': b4.id
                }]),
            CompiledSQL("DELETE FROM person WHERE person.id = :id",
                        lambda ctx: [{
                            'id': p.id
                        }]),
            CompiledSQL(
                "DELETE FROM ball WHERE ball.id = :id", lambda ctx: [
                    {
                        'id': b.id
                    }, {
                        'id': b2.id
                    }, {
                        'id': b3.id
                    }, {
                        'id': b4.id
                    }
                ]))
Exemple #17
0
    def test_bidirectional_multilevel_save(self):
        Node, nodes = self.classes.Node, self.tables.nodes

        mapper(Node,
               nodes,
               properties={
                   'children':
                   relationship(Node,
                                backref=backref('parent',
                                                remote_side=nodes.c.id))
               })
        sess = create_session()
        n1 = Node(data='n1')
        n1.children.append(Node(data='n11'))
        n12 = Node(data='n12')
        n1.children.append(n12)
        n1.children.append(Node(data='n13'))
        n1.children[1].children.append(Node(data='n121'))
        n1.children[1].children.append(Node(data='n122'))
        n1.children[1].children.append(Node(data='n123'))
        sess.add(n1)
        self.assert_sql_execution(
            testing.db,
            sess.flush,
            CompiledSQL(
                "INSERT INTO nodes (parent_id, data) VALUES "
                "(:parent_id, :data)", lambda ctx: {
                    'parent_id': None,
                    'data': 'n1'
                }),
            CompiledSQL(
                "INSERT INTO nodes (parent_id, data) VALUES "
                "(:parent_id, :data)", lambda ctx: {
                    'parent_id': n1.id,
                    'data': 'n11'
                }),
            CompiledSQL(
                "INSERT INTO nodes (parent_id, data) VALUES "
                "(:parent_id, :data)", lambda ctx: {
                    'parent_id': n1.id,
                    'data': 'n12'
                }),
            CompiledSQL(
                "INSERT INTO nodes (parent_id, data) VALUES "
                "(:parent_id, :data)", lambda ctx: {
                    'parent_id': n1.id,
                    'data': 'n13'
                }),
            CompiledSQL(
                "INSERT INTO nodes (parent_id, data) VALUES "
                "(:parent_id, :data)", lambda ctx: {
                    'parent_id': n12.id,
                    'data': 'n121'
                }),
            CompiledSQL(
                "INSERT INTO nodes (parent_id, data) VALUES "
                "(:parent_id, :data)", lambda ctx: {
                    'parent_id': n12.id,
                    'data': 'n122'
                }),
            CompiledSQL(
                "INSERT INTO nodes (parent_id, data) VALUES "
                "(:parent_id, :data)", lambda ctx: {
                    'parent_id': n12.id,
                    'data': 'n123'
                }),
        )
Exemple #18
0
    def test_many_to_one_delete_unloaded(self):
        users, Address, addresses, User = (self.tables.users,
                                           self.classes.Address,
                                           self.tables.addresses,
                                           self.classes.User)

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

        parent = User(name='p1')
        c1, c2 = Address(email_address='c1', parent=parent), \
                    Address(email_address='c2', parent=parent)

        session = Session()
        session.add_all([c1, c2])
        session.add(parent)

        session.flush()

        pid = parent.id
        c1id = c1.id
        c2id = c2.id

        session.expire(parent)
        session.expire(c1)
        session.expire(c2)

        session.delete(c1)
        session.delete(c2)
        session.delete(parent)

        # testing that relationships
        # are loaded even if all ids/references are
        # expired
        self.assert_sql_execution(
            testing.db,
            session.flush,
            AllOf(
                # [ticket:2002] - ensure the m2os are loaded.
                # the selects here are in fact unexpiring
                # each row - the m2o comes from the identity map.
                # the User row might be handled before or the addresses
                # are loaded so need to use AllOf
                CompiledSQL(
                    "SELECT addresses.id AS addresses_id, addresses.user_id AS "
                    "addresses_user_id, addresses.email_address AS "
                    "addresses_email_address FROM addresses WHERE addresses.id = "
                    ":param_1", lambda ctx: {'param_1': c1id}),
                CompiledSQL(
                    "SELECT addresses.id AS addresses_id, addresses.user_id AS "
                    "addresses_user_id, addresses.email_address AS "
                    "addresses_email_address FROM addresses WHERE addresses.id = "
                    ":param_1", lambda ctx: {'param_1': c2id}),
                CompiledSQL(
                    "SELECT users.id AS users_id, users.name AS users_name "
                    "FROM users WHERE users.id = :param_1",
                    lambda ctx: {'param_1': pid}),
                CompiledSQL("DELETE FROM addresses WHERE addresses.id = :id",
                            lambda ctx: [{
                                'id': c1id
                            }, {
                                'id': c2id
                            }]),
                CompiledSQL("DELETE FROM users WHERE users.id = :id",
                            lambda ctx: {'id': pid}),
            ),
        )
Exemple #19
0
    def test_delete_unloaded_m2o(self):
        Node, nodes = self.classes.Node, self.tables.nodes

        mapper(
            Node,
            nodes,
            properties={'parent': relationship(Node, remote_side=nodes.c.id)})

        parent = Node()
        c1, c2 = Node(parent=parent), Node(parent=parent)

        session = Session()
        session.add_all([c1, c2])
        session.add(parent)

        session.flush()

        pid = parent.id
        c1id = c1.id
        c2id = c2.id

        session.expire(parent)
        session.expire(c1)
        session.expire(c2)

        session.delete(c1)
        session.delete(c2)
        session.delete(parent)

        # testing that relationships
        # are loaded even if all ids/references are
        # expired
        self.assert_sql_execution(
            testing.db,
            session.flush,
            AllOf(
                # ensure all three m2os are loaded.
                # the selects here are in fact unexpiring
                # each row - the m2o comes from the identity map.
                CompiledSQL(
                    "SELECT nodes.id AS nodes_id, nodes.parent_id AS "
                    "nodes_parent_id, "
                    "nodes.data AS nodes_data FROM nodes "
                    "WHERE nodes.id = :param_1", lambda ctx: {'param_1': pid}),
                CompiledSQL(
                    "SELECT nodes.id AS nodes_id, nodes.parent_id AS "
                    "nodes_parent_id, "
                    "nodes.data AS nodes_data FROM nodes "
                    "WHERE nodes.id = :param_1",
                    lambda ctx: {'param_1': c1id}),
                CompiledSQL(
                    "SELECT nodes.id AS nodes_id, nodes.parent_id AS "
                    "nodes_parent_id, "
                    "nodes.data AS nodes_data FROM nodes "
                    "WHERE nodes.id = :param_1",
                    lambda ctx: {'param_1': c2id}),
                CompiledSQL("DELETE FROM nodes WHERE nodes.id = :id",
                            lambda ctx: [{
                                'id': c1id
                            }, {
                                'id': c2id
                            }]),
                CompiledSQL("DELETE FROM nodes WHERE nodes.id = :id",
                            lambda ctx: {'id': pid}),
            ),
        )
Exemple #20
0
    def test_one(self):
        child1, child2, child3, Parent, parent, Child1, Child2, Child3 = (
            self.tables.child1, self.tables.child2, self.tables.child3,
            self.classes.Parent, self.tables.parent, self.classes.Child1,
            self.classes.Child2, self.classes.Child3)

        mapper(Parent,
               parent,
               properties={
                   'c1s':
                   relationship(Child1,
                                primaryjoin=child1.c.parent_id == parent.c.id),
                   'c2s':
                   relationship(Child2,
                                primaryjoin=child2.c.parent_id == parent.c.id),
                   'c3s':
                   relationship(Child3,
                                primaryjoin=child3.c.parent_id == parent.c.id),
                   'c1':
                   relationship(Child1,
                                primaryjoin=child1.c.id == parent.c.c1_id,
                                post_update=True),
                   'c2':
                   relationship(Child2,
                                primaryjoin=child2.c.id == parent.c.c2_id,
                                post_update=True),
                   'c3':
                   relationship(Child3,
                                primaryjoin=child3.c.id == parent.c.c3_id,
                                post_update=True),
               })
        mapper(Child1, child1)
        mapper(Child2, child2)
        mapper(Child3, child3)

        sess = create_session()

        p1 = Parent('p1')
        c11, c12, c13 = Child1('c1'), Child1('c2'), Child1('c3')
        c21, c22, c23 = Child2('c1'), Child2('c2'), Child2('c3')
        c31, c32, c33 = Child3('c1'), Child3('c2'), Child3('c3')

        p1.c1s = [c11, c12, c13]
        p1.c2s = [c21, c22, c23]
        p1.c3s = [c31, c32, c33]
        sess.add(p1)
        sess.flush()

        p1.c1 = c12
        p1.c2 = c23
        p1.c3 = c31

        self.assert_sql_execution(
            testing.db, sess.flush,
            CompiledSQL(
                "UPDATE parent SET c1_id=:c1_id, c2_id=:c2_id, "
                "c3_id=:c3_id WHERE parent.id = :parent_id", lambda ctx: {
                    'c2_id': c23.id,
                    'parent_id': p1.id,
                    'c1_id': c12.id,
                    'c3_id': c31.id
                }))

        p1.c1 = p1.c2 = p1.c3 = None

        self.assert_sql_execution(
            testing.db, sess.flush,
            CompiledSQL(
                "UPDATE parent SET c1_id=:c1_id, c2_id=:c2_id, "
                "c3_id=:c3_id WHERE parent.id = :parent_id", lambda ctx: {
                    'c2_id': None,
                    'parent_id': p1.id,
                    'c1_id': None,
                    'c3_id': None
                }))