~ubuntu-branches/debian/sid/sqlalchemy/sid

« back to all changes in this revision

Viewing changes to test/orm/inheritance/test_basic.py

  • Committer: Package Import Robot
  • Author(s): Piotr Ożarowski
  • Date: 2014-06-27 20:17:13 UTC
  • mfrom: (1.4.28)
  • Revision ID: package-import@ubuntu.com-20140627201713-g6p1kq8q1qenztrv
Tags: 0.9.6-1
* New upstream release
* Remove Python 3.X build tag files, thanks to Matthias Urlichs for the
  patch (closes: #747852)
* python-fdb isn't in the Debian archive yet so default dialect for firebird://
  URLs is changed to obsolete kinterbasdb, thanks to Russell Stuart for the
  patch (closes: #752145)

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
from sqlalchemy.orm import *
6
6
from sqlalchemy.orm.util import instance_str
7
7
from sqlalchemy.orm import exc as orm_exc, attributes
8
 
from sqlalchemy.testing.assertsql import AllOf, CompiledSQL
 
8
from sqlalchemy.testing.assertsql import AllOf, CompiledSQL, Or
9
9
from sqlalchemy.sql import table, column
10
10
from sqlalchemy import testing
11
11
from sqlalchemy.testing import engines
28
28
 
29
29
        bar = Table('bar', metadata,
30
30
            Column('id', Integer, ForeignKey('foo.id'), primary_key=True),
31
 
            Column('data', String(20)))
 
31
            Column('bar_data', String(20)))
32
32
 
33
33
        blub = Table('blub', metadata,
34
34
            Column('id', Integer, ForeignKey('bar.id'), primary_key=True),
35
35
            Column('foo_id', Integer, ForeignKey('foo.id'), nullable=False),
36
 
            Column('data', String(20)))
 
36
            Column('blub_data', String(20)))
37
37
 
38
38
    def test_basic(self):
39
39
        class Foo(object):
184
184
                Column('x', String(10)),
185
185
                Column('q', String(10)))
186
186
        t2 = Table('t2', metadata,
187
 
                Column('id', Integer, primary_key=True,
 
187
                Column('t2id', Integer, primary_key=True,
188
188
                            test_needs_autoincrement=True),
189
189
                Column('y', String(10)),
190
190
                Column('xid', ForeignKey('t1.id')))
583
583
                        polymorphic_identity='a')
584
584
        mapper(B, table_b, inherits=A,
585
585
                        polymorphic_on=table_b.c.class_name,
586
 
                        polymorphic_identity='b')
 
586
                        polymorphic_identity='b',
 
587
                        properties=dict(class_name=[table_a.c.class_name, table_b.c.class_name]))
587
588
        mapper(C, table_c, inherits=B,
588
589
                        polymorphic_identity='c')
589
590
        mapper(D, inherits=B,
854
855
 
855
856
        bar = Table('bar', metadata,
856
857
            Column('id', Integer, ForeignKey('foo.id'), primary_key=True),
857
 
            Column('data', String(20)))
 
858
            Column('bar_data', String(20)))
858
859
 
859
860
        blub = Table('blub', metadata,
860
 
            Column('id', Integer, primary_key=True, test_needs_autoincrement=True),
 
861
            Column('blub_id', Integer, primary_key=True, test_needs_autoincrement=True),
861
862
            Column('foo_id', Integer, ForeignKey('foo.id')),
862
863
            Column('bar_id', Integer, ForeignKey('bar.id')),
863
 
            Column('data', String(20)))
 
864
            Column('blub_data', String(20)))
864
865
 
865
866
    @classmethod
866
867
    def setup_classes(cls):
957
958
                    Column('data', String(30)))
958
959
        bar = Table('bar', metadata,
959
960
                    Column('id', Integer, ForeignKey('foo.id'), primary_key=True),
960
 
                    Column('data', String(30)))
 
961
                    Column('bar_data', String(30)))
961
962
 
962
963
        bar_foo = Table('bar_foo', metadata,
963
964
                        Column('bar_id', Integer, ForeignKey('bar.id')),
1095
1096
 
1096
1097
        # create an Admin, and append a Role.  the dependency processors
1097
1098
        # corresponding to the "roles" attribute for the Admin mapper and the User mapper
1098
 
        # have to ensure that two dependency processors dont fire off and insert the
 
1099
        # have to ensure that two dependency processors don't fire off and insert the
1099
1100
        # many to many row twice.
1100
1101
        a = Admin()
1101
1102
        a.roles.append(adminrole)
1175
1176
        A, B, C = cls.classes.A, cls.classes.B, cls.classes.C
1176
1177
        mapper(A, cls.tables.a)
1177
1178
        mapper(B, cls.tables.b, inherits=A,
1178
 
                    inherit_condition=cls.tables.a.c.id == cls.tables.b.c.id)
 
1179
                    inherit_condition=cls.tables.a.c.id == cls.tables.b.c.id,
 
1180
                    inherit_foreign_keys=cls.tables.b.c.id)
1179
1181
        mapper(C, cls.tables.c, inherits=A,
1180
 
                    inherit_condition=cls.tables.a.c.id == cls.tables.c.c.id)
 
1182
                    inherit_condition=cls.tables.a.c.id == cls.tables.c.c.id,
 
1183
                    inherit_foreign_keys=cls.tables.c.c.id)
1181
1184
 
1182
1185
    def test_ordering(self):
1183
1186
        B, C = self.classes.B, self.classes.C
1345
1348
                )
1346
1349
 
1347
1350
        employee_table = Table("employees", metadata,
1348
 
                Column("id", Integer, primary_key=True, test_needs_autoincrement=True),
 
1351
                Column("eid", Integer, primary_key=True, test_needs_autoincrement=True),
1349
1352
                Column("salary", Integer),
1350
1353
                Column("person_id", Integer, ForeignKey("persons.id")),
1351
1354
                )
1375
1378
        person_mapper = mapper(Person, person_table)
1376
1379
        mapper(Employee, employee_table, inherits=person_mapper,
1377
1380
                        properties={'pid':person_table.c.id,
1378
 
                                    'eid':employee_table.c.id})
 
1381
                                    'eid':employee_table.c.eid})
1379
1382
        self._do_test(False)
1380
1383
 
1381
1384
    def test_explicit_composite_pk(self):
1382
1385
        person_mapper = mapper(Person, person_table)
1383
1386
        mapper(Employee, employee_table,
1384
1387
                    inherits=person_mapper,
1385
 
                    primary_key=[person_table.c.id, employee_table.c.id])
 
1388
                    properties=dict(id=[employee_table.c.eid, person_table.c.id]),
 
1389
                    primary_key=[person_table.c.id, employee_table.c.eid])
1386
1390
        assert_raises_message(sa_exc.SAWarning,
1387
1391
                                    r"On mapper Mapper\|Employee\|employees, "
1388
1392
                                    "primary key column 'persons.id' is being "
1389
 
                                    "combined with distinct primary key column 'employees.id' "
 
1393
                                    "combined with distinct primary key column 'employees.eid' "
1390
1394
                                    "in attribute 'id'.  Use explicit properties to give "
1391
1395
                                    "each column its own mapped attribute name.",
1392
1396
            self._do_test, True
1487
1491
 
1488
1492
    @classmethod
1489
1493
    def define_tables(cls, metadata):
1490
 
        global base, subtable
 
1494
        global base, subtable, subtable_two
1491
1495
 
1492
1496
        base = Table('base', metadata,
1493
1497
            Column('base_id', Integer, primary_key=True, test_needs_autoincrement=True),
1499
1503
            Column('base_id', Integer, ForeignKey('base.base_id'), primary_key=True),
1500
1504
            Column('subdata', String(255))
1501
1505
        )
 
1506
        subtable_two = Table('subtable_two', metadata,
 
1507
            Column('base_id', Integer, primary_key=True),
 
1508
            Column('fk_base_id', Integer, ForeignKey('base.base_id')),
 
1509
            Column('subdata', String(255))
 
1510
        )
 
1511
 
1502
1512
 
1503
1513
    def test_plain(self):
1504
1514
        # control case
1609
1619
        # an exception in 0.7 due to the implicit conflict.
1610
1620
        assert_raises(sa_exc.InvalidRequestError, go)
1611
1621
 
 
1622
    def test_pk_fk_different(self):
 
1623
        class Base(object):
 
1624
            pass
 
1625
        class Sub(Base):
 
1626
            pass
 
1627
 
 
1628
        mapper(Base, base)
 
1629
 
 
1630
        def go():
 
1631
            mapper(Sub, subtable_two, inherits=Base)
 
1632
        assert_raises_message(
 
1633
            sa_exc.SAWarning,
 
1634
            "Implicitly combining column base.base_id with "
 
1635
            "column subtable_two.base_id under attribute 'base_id'",
 
1636
            go
 
1637
        )
 
1638
 
1612
1639
    def test_plain_descriptor(self):
1613
1640
        """test that descriptors prevent inheritance from propigating properties to subclasses."""
1614
1641
 
1716
1743
        Table('sub', metadata,
1717
1744
            Column('id', Integer, ForeignKey('base.id'), primary_key=True),
1718
1745
            Column('sub', String(50)),
1719
 
            Column('counter', Integer, server_default="1"),
1720
 
            Column('counter2', Integer, server_default="1")
 
1746
            Column('subcounter', Integer, server_default="1"),
 
1747
            Column('subcounter2', Integer, server_default="1")
1721
1748
        )
1722
1749
        Table('subsub', metadata,
1723
1750
            Column('id', Integer, ForeignKey('sub.id'), primary_key=True),
1724
 
            Column('counter2', Integer, server_default="1")
 
1751
            Column('subsubcounter2', Integer, server_default="1")
1725
1752
        )
1726
1753
        Table('with_comp', metadata,
1727
1754
            Column('id', Integer, ForeignKey('base.id'), primary_key=True),
1743
1770
        mapper(Base, base)
1744
1771
        mapper(JoinBase, base.outerjoin(sub), properties=util.OrderedDict(
1745
1772
                [('id', [base.c.id, sub.c.id]),
1746
 
                ('counter', [base.c.counter, sub.c.counter])])
 
1773
                ('counter', [base.c.counter, sub.c.subcounter])])
1747
1774
            )
1748
1775
        mapper(SubJoinBase, inherits=JoinBase)
1749
1776
 
1765
1792
            go,
1766
1793
            CompiledSQL(
1767
1794
                "SELECT base.id AS base_id, sub.id AS sub_id, "
1768
 
                "base.counter AS base_counter, sub.counter AS sub_counter, "
1769
 
                "base.data AS base_data, "
1770
 
                "base.type AS base_type, sub.sub AS sub_sub, "
1771
 
                "sub.counter2 AS sub_counter2 FROM base "
1772
 
                "LEFT OUTER JOIN sub ON base.id = sub.id "
 
1795
                "base.counter AS base_counter, sub.subcounter AS sub_subcounter, "
 
1796
                "base.data AS base_data, base.type AS base_type, "
 
1797
                "sub.sub AS sub_sub, sub.subcounter2 AS sub_subcounter2 "
 
1798
                "FROM base LEFT OUTER JOIN sub ON base.id = sub.id "
1773
1799
                "WHERE base.id = :param_1",
1774
1800
                {'param_1': sjb_id}
1775
1801
            ),
1914
1940
                ),
1915
1941
        )
1916
1942
        def go():
1917
 
            eq_( s1.counter2, 1 )
 
1943
            eq_( s1.subcounter2, 1 )
1918
1944
        self.assert_sql_execution(
1919
1945
            testing.db,
1920
1946
            go,
1921
1947
            CompiledSQL(
1922
 
                "SELECT sub.counter AS sub_counter, base.counter AS base_counter, "
1923
 
                "sub.counter2 AS sub_counter2 FROM base JOIN sub ON "
1924
 
                "base.id = sub.id WHERE base.id = :param_1",
 
1948
                "SELECT base.counter AS base_counter, sub.subcounter AS sub_subcounter, "
 
1949
                "sub.subcounter2 AS sub_subcounter2 FROM base JOIN sub "
 
1950
                "ON base.id = sub.id WHERE base.id = :param_1",
1925
1951
                lambda ctx:{'param_1': s1.id}
1926
1952
            ),
1927
1953
        )
1939
1965
 
1940
1966
        s1 = Sub()
1941
1967
        assert m._optimized_get_statement(attributes.instance_state(s1),
1942
 
                                ['counter2']) is None
 
1968
                                ['subcounter2']) is None
1943
1969
 
1944
1970
        # loads s1.id as None
1945
1971
        eq_(s1.id, None)
1946
1972
 
1947
1973
        # this now will come up with a value of None for id - should reject
1948
1974
        assert m._optimized_get_statement(attributes.instance_state(s1),
1949
 
                                ['counter2']) is None
 
1975
                                ['subcounter2']) is None
1950
1976
 
1951
1977
        s1.id = 1
1952
1978
        attributes.instance_state(s1)._commit_all(s1.__dict__, None)
1953
1979
        assert m._optimized_get_statement(attributes.instance_state(s1),
1954
 
                                ['counter2']) is not None
 
1980
                                ['subcounter2']) is not None
1955
1981
 
1956
1982
    def test_load_expired_on_pending_twolevel(self):
1957
1983
        base, sub, subsub = (self.tables.base,
1970
1996
        mapper(Sub, sub, inherits=Base, polymorphic_identity='sub')
1971
1997
        mapper(SubSub, subsub, inherits=Sub, polymorphic_identity='subsub')
1972
1998
        sess = Session()
1973
 
        s1 = SubSub(data='s1', counter=1)
 
1999
        s1 = SubSub(data='s1', counter=1, subcounter=2)
1974
2000
        sess.add(s1)
1975
2001
        self.assert_sql_execution(
1976
2002
                testing.db,
1981
2007
                    [{'data':'s1','type':'subsub','counter':1}]
1982
2008
                ),
1983
2009
                CompiledSQL(
1984
 
                    "INSERT INTO sub (id, sub, counter) VALUES "
1985
 
                    "(:id, :sub, :counter)",
1986
 
                    lambda ctx:[{'counter': 1, 'sub': None, 'id': s1.id}]
 
2010
                    "INSERT INTO sub (id, sub, subcounter) VALUES "
 
2011
                    "(:id, :sub, :subcounter)",
 
2012
                    lambda ctx:[{'subcounter': 2, 'sub': None, 'id': s1.id}]
1987
2013
                ),
1988
2014
                CompiledSQL(
1989
2015
                    "INSERT INTO subsub (id) VALUES (:id)",
1993
2019
 
1994
2020
        def go():
1995
2021
            eq_(
1996
 
                s1.counter2, 1
 
2022
                s1.subcounter2, 1
1997
2023
            )
1998
2024
        self.assert_sql_execution(
1999
2025
            testing.db,
2000
2026
            go,
2001
 
            CompiledSQL(
2002
 
                "SELECT subsub.counter2 AS subsub_counter2, "
2003
 
                "sub.counter2 AS sub_counter2 FROM subsub, sub "
2004
 
                "WHERE :param_1 = sub.id AND sub.id = subsub.id",
2005
 
                lambda ctx:{'param_1': s1.id}
2006
 
            ),
 
2027
            Or(
 
2028
                CompiledSQL(
 
2029
                    "SELECT subsub.subsubcounter2 AS subsub_subsubcounter2, "
 
2030
                    "sub.subcounter2 AS sub_subcounter2 FROM subsub, sub "
 
2031
                    "WHERE :param_1 = sub.id AND sub.id = subsub.id",
 
2032
                    lambda ctx: {'param_1': s1.id}
 
2033
                ),
 
2034
                CompiledSQL(
 
2035
                    "SELECT sub.subcounter2 AS sub_subcounter2, "
 
2036
                    "subsub.subsubcounter2 AS subsub_subsubcounter2 "
 
2037
                    "FROM sub, subsub "
 
2038
                    "WHERE :param_1 = sub.id AND sub.id = subsub.id",
 
2039
                    lambda ctx: {'param_1': s1.id}
 
2040
                ),
 
2041
            )
2007
2042
        )
2008
2043
 
2009
2044
class TransientInheritingGCTest(fixtures.TestBase):