Example #1
0
    def test_relationship(self):
        pjoin = polymorphic_union(
            {"manager": managers_table, "engineer": engineers_table},
            "type",
            "pjoin",
        )
        mapper(
            Company,
            companies,
            properties={"employees": relationship(Employee)},
        )
        employee_mapper = mapper(Employee, pjoin, polymorphic_on=pjoin.c.type)
        manager_mapper = mapper(
            Manager,
            managers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="manager",
        )
        engineer_mapper = mapper(
            Engineer,
            engineers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="engineer",
        )
        session = create_session()
        c = Company()
        c.employees.append(Manager("Tom", "knows how to manage things"))
        c.employees.append(Engineer("Kurt", "knows how to hack"))
        session.add(c)
        session.flush()
        session.expunge_all()

        def go():
            c2 = session.query(Company).get(c.id)
            assert set([repr(x) for x in c2.employees]) == set(
                [
                    "Engineer Kurt knows how to hack",
                    "Manager Tom knows how to manage things",
                ]
            )

        self.assert_sql_count(testing.db, go, 2)
        session.expunge_all()

        def go():
            c2 = (
                session.query(Company)
                .options(joinedload(Company.employees))
                .get(c.id)
            )
            assert set([repr(x) for x in c2.employees]) == set(
                [
                    "Engineer Kurt knows how to hack",
                    "Manager Tom knows how to manage things",
                ]
            )

        self.assert_sql_count(testing.db, go, 1)
Example #2
0
 def _get_polymorphics(cls):
     people, engineers, managers, boss = \
         cls.tables.people, cls.tables.engineers, \
         cls.tables.managers, cls.tables.boss
     person_join = polymorphic_union({
             'engineer':people.join(engineers),
             'manager':people.join(managers)},
         None, 'pjoin')
     manager_join = people.join(managers).outerjoin(boss)
     person_with_polymorphic = (
         [Person, Manager, Engineer], person_join)
     manager_with_polymorphic = ('*', manager_join)
     return person_with_polymorphic,\
         manager_with_polymorphic
    def test_explicit(self):
        engineers = Table(
            'engineers', Base.metadata,
            Column('id',
                   Integer, primary_key=True, test_needs_autoincrement=True),
            Column('name', String(50)),
            Column('primary_language', String(50)))
        managers = Table('managers', Base.metadata,
                         Column('id', Integer, primary_key=True,
                                test_needs_autoincrement=True),
                         Column('name', String(50)),
                         Column('golf_swing', String(50))
                         )
        boss = Table('boss', Base.metadata,
                     Column('id', Integer, primary_key=True,
                            test_needs_autoincrement=True),
                     Column('name', String(50)),
                     Column('golf_swing', String(50))
                     )
        punion = polymorphic_union({
            'engineer': engineers,
            'manager': managers,
            'boss': boss}, 'type', 'punion')

        class Employee(Base, fixtures.ComparableEntity):

            __table__ = punion
            __mapper_args__ = {'polymorphic_on': punion.c.type}

        class Engineer(Employee):

            __table__ = engineers
            __mapper_args__ = {'polymorphic_identity': 'engineer',
                               'concrete': True}

        class Manager(Employee):

            __table__ = managers
            __mapper_args__ = {'polymorphic_identity': 'manager',
                               'concrete': True}

        class Boss(Manager):
            __table__ = boss
            __mapper_args__ = {'polymorphic_identity': 'boss',
                               'concrete': True}

        self._roundtrip(Employee, Manager, Engineer, Boss)
Example #4
0
 def _get_polymorphics(cls):
     people, engineers, managers, boss = (
         cls.tables.people,
         cls.tables.engineers,
         cls.tables.managers,
         cls.tables.boss,
     )
     person_join = polymorphic_union(
         {
             "engineer": people.join(engineers),
             "manager": people.join(managers),
         },
         None,
         "pjoin",
     )
     manager_join = people.join(managers).outerjoin(boss)
     person_with_polymorphic = ([Person, Manager, Engineer], person_join)
     manager_with_polymorphic = ("*", manager_join)
     return person_with_polymorphic, manager_with_polymorphic
Example #5
0
    def test_keys(self):
        pjoin = polymorphic_union(
            {"refugee": refugees_table, "office": offices_table},
            "type",
            "pjoin",
        )

        class Location(object):
            pass

        class Refugee(Location):
            pass

        class Office(Location):
            pass

        location_mapper = mapper(
            Location,
            pjoin,
            polymorphic_on=pjoin.c.type,
            polymorphic_identity="location",
        )
        office_mapper = mapper(
            Office,
            offices_table,
            inherits=location_mapper,
            concrete=True,
            polymorphic_identity="office",
        )
        refugee_mapper = mapper(
            Refugee,
            refugees_table,
            inherits=location_mapper,
            concrete=True,
            polymorphic_identity="refugee",
        )
        sess = create_session()
        eq_(sess.query(Refugee).get(1).name, "refugee1")
        eq_(sess.query(Refugee).get(2).name, "refugee2")
        eq_(sess.query(Office).get(1).name, "office1")
        eq_(sess.query(Office).get(2).name, "office2")
Example #6
0
 def test_basic(self):
     pjoin = polymorphic_union(
         {"manager": managers_table, "engineer": engineers_table},
         "type",
         "pjoin",
     )
     employee_mapper = mapper(Employee, pjoin, polymorphic_on=pjoin.c.type)
     manager_mapper = mapper(
         Manager,
         managers_table,
         inherits=employee_mapper,
         concrete=True,
         polymorphic_identity="manager",
     )
     engineer_mapper = mapper(
         Engineer,
         engineers_table,
         inherits=employee_mapper,
         concrete=True,
         polymorphic_identity="engineer",
     )
     session = create_session()
     session.add(Manager("Tom", "knows how to manage things"))
     session.add(Engineer("Kurt", "knows how to hack"))
     session.flush()
     session.expunge_all()
     assert set([repr(x) for x in session.query(Employee)]) == set(
         [
             "Engineer Kurt knows how to hack",
             "Manager Tom knows how to manage things",
         ]
     )
     assert set([repr(x) for x in session.query(Manager)]) == set(
         ["Manager Tom knows how to manage things"]
     )
     assert set([repr(x) for x in session.query(Engineer)]) == set(
         ["Engineer Kurt knows how to hack"]
     )
     manager = session.query(Manager).one()
     session.expire(manager, ["manager_data"])
     eq_(manager.manager_data, "knows how to manage things")
Example #7
0
    def _get_polymorphics(cls):
        people, engineers, managers, boss = (
            cls.tables.people,
            cls.tables.engineers,
            cls.tables.managers,
            cls.tables.boss,
        )
        person_join = polymorphic_union(
            util.OrderedDict(
                [
                    ("engineer", people.join(engineers)),
                    ("manager", people.join(managers)),
                ]
            ),
            None,
            "pjoin",
        )

        manager_join = people.join(managers).outerjoin(boss)
        person_with_polymorphic = ([Person, Manager, Engineer], person_join)
        manager_with_polymorphic = ("*", manager_join)
        return person_with_polymorphic, manager_with_polymorphic
Example #8
0
        def test_roundtrip(self):
            parent_table = {"a": ta, "b": tb, "c": tc}[parent]
            child_table = {"a": ta, "b": tb, "c": tc}[child]

            remote_side = None

            if direction == MANYTOONE:
                foreign_keys = [parent_table.c.child_id]
            elif direction == ONETOMANY:
                foreign_keys = [child_table.c.parent_id]

            atob = ta.c.id == tb.c.id
            btoc = tc.c.id == tb.c.id

            if direction == ONETOMANY:
                relationshipjoin = parent_table.c.id == child_table.c.parent_id
            elif direction == MANYTOONE:
                relationshipjoin = parent_table.c.child_id == child_table.c.id
                if parent is child:
                    remote_side = [child_table.c.id]

            abcjoin = polymorphic_union(
                {
                    "a":
                    ta.select(
                        tb.c.id == None,  # noqa
                        from_obj=[ta.outerjoin(tb, onclause=atob)],
                    ),
                    "b":
                    ta.join(tb, onclause=atob).outerjoin(
                        tc, onclause=btoc).select(
                            tc.c.id == None).reduce_columns(),  # noqa
                    "c":
                    tc.join(tb, onclause=btoc).join(ta, onclause=atob),
                },
                "type",
                "abcjoin",
            )

            bcjoin = polymorphic_union(
                {
                    "b":
                    ta.join(tb, onclause=atob).outerjoin(
                        tc, onclause=btoc).select(
                            tc.c.id == None).reduce_columns(),  # noqa
                    "c":
                    tc.join(tb, onclause=btoc).join(ta, onclause=atob),
                },
                "type",
                "bcjoin",
            )

            class A(object):
                def __init__(self, name):
                    self.a_data = name

            class B(A):
                pass

            class C(B):
                pass

            mapper(
                A,
                ta,
                polymorphic_on=abcjoin.c.type,
                with_polymorphic=("*", abcjoin),
                polymorphic_identity="a",
            )
            mapper(
                B,
                tb,
                polymorphic_on=bcjoin.c.type,
                with_polymorphic=("*", bcjoin),
                polymorphic_identity="b",
                inherits=A,
                inherit_condition=atob,
            )
            mapper(
                C,
                tc,
                polymorphic_identity="c",
                inherits=B,
                inherit_condition=btoc,
            )

            parent_mapper = class_mapper({ta: A, tb: B, tc: C}[parent_table])
            child_mapper = class_mapper({ta: A, tb: B, tc: C}[child_table])

            parent_class = parent_mapper.class_
            child_class = child_mapper.class_

            parent_mapper.add_property(
                "collection",
                relationship(
                    child_mapper,
                    primaryjoin=relationshipjoin,
                    foreign_keys=foreign_keys,
                    order_by=child_mapper.c.id,
                    remote_side=remote_side,
                    uselist=True,
                ),
            )

            sess = create_session()

            parent_obj = parent_class("parent1")
            child_obj = child_class("child1")
            somea = A("somea")
            someb = B("someb")
            somec = C("somec")

            # print "APPENDING", parent.__class__.__name__ , "TO",
            # child.__class__.__name__

            sess.add(parent_obj)
            parent_obj.collection.append(child_obj)
            if direction == ONETOMANY:
                child2 = child_class("child2")
                parent_obj.collection.append(child2)
                sess.add(child2)
            elif direction == MANYTOONE:
                parent2 = parent_class("parent2")
                parent2.collection.append(child_obj)
                sess.add(parent2)
            sess.add(somea)
            sess.add(someb)
            sess.add(somec)
            sess.flush()
            sess.expunge_all()

            # assert result via direct get() of parent object
            result = sess.query(parent_class).get(parent_obj.id)
            assert result.id == parent_obj.id
            assert result.collection[0].id == child_obj.id
            if direction == ONETOMANY:
                assert result.collection[1].id == child2.id
            elif direction == MANYTOONE:
                result2 = sess.query(parent_class).get(parent2.id)
                assert result2.id == parent2.id
                assert result2.collection[0].id == child_obj.id

            sess.expunge_all()

            # assert result via polymorphic load of parent object
            result = sess.query(A).filter_by(id=parent_obj.id).one()
            assert result.id == parent_obj.id
            assert result.collection[0].id == child_obj.id
            if direction == ONETOMANY:
                assert result.collection[1].id == child2.id
            elif direction == MANYTOONE:
                result2 = sess.query(A).filter_by(id=parent2.id).one()
                assert result2.id == parent2.id
                assert result2.collection[0].id == child_obj.id
    def setup_mappers(cls):
        parent, child, direction = cls.parent, cls.child, cls.direction
        ta, tb, tc = cls.tables("a", "b", "c")
        parent_table = {"a": ta, "b": tb, "c": tc}[parent]
        child_table = {"a": ta, "b": tb, "c": tc}[child]

        remote_side = None

        if direction == MANYTOONE:
            foreign_keys = [parent_table.c.child_id]
        elif direction == ONETOMANY:
            foreign_keys = [child_table.c.parent_id]

        atob = ta.c.id == tb.c.id
        btoc = tc.c.id == tb.c.id

        if direction == ONETOMANY:
            relationshipjoin = parent_table.c.id == child_table.c.parent_id
        elif direction == MANYTOONE:
            relationshipjoin = parent_table.c.child_id == child_table.c.id
            if parent is child:
                remote_side = [child_table.c.id]

        abcjoin = polymorphic_union(
            {
                "a":
                ta.select().where(tb.c.id == None)  # noqa
                .select_from(ta.outerjoin(tb, onclause=atob)).subquery(),
                "b":
                ta.join(tb, onclause=atob).outerjoin(
                    tc, onclause=btoc).select().where(
                        tc.c.id == None).reduce_columns().subquery(),  # noqa
                "c":
                tc.join(tb, onclause=btoc).join(ta, onclause=atob),
            },
            "type",
            "abcjoin",
        )

        bcjoin = polymorphic_union(
            {
                "b":
                ta.join(tb, onclause=atob).outerjoin(
                    tc, onclause=btoc).select().where(
                        tc.c.id == None).reduce_columns().subquery(),  # noqa
                "c":
                tc.join(tb, onclause=btoc).join(ta, onclause=atob),
            },
            "type",
            "bcjoin",
        )

        class A(cls.Comparable):
            def __init__(self, name):
                self.a_data = name

        class B(A):
            pass

        class C(B):
            pass

        cls.mapper_registry.map_imperatively(
            A,
            ta,
            polymorphic_on=abcjoin.c.type,
            with_polymorphic=("*", abcjoin),
            polymorphic_identity="a",
        )
        cls.mapper_registry.map_imperatively(
            B,
            tb,
            polymorphic_on=bcjoin.c.type,
            with_polymorphic=("*", bcjoin),
            polymorphic_identity="b",
            inherits=A,
            inherit_condition=atob,
        )
        cls.mapper_registry.map_imperatively(
            C,
            tc,
            polymorphic_identity="c",
            with_polymorphic=("*", tc.join(tb, btoc).join(ta, atob)),
            inherits=B,
            inherit_condition=btoc,
        )

        parent_mapper = class_mapper({ta: A, tb: B, tc: C}[parent_table])
        child_mapper = class_mapper({ta: A, tb: B, tc: C}[child_table])

        parent_mapper.add_property(
            "collection",
            relationship(
                child_mapper,
                primaryjoin=relationshipjoin,
                foreign_keys=foreign_keys,
                order_by=child_mapper.c.id,
                remote_side=remote_side,
                uselist=True,
            ),
        )
Example #10
0
    def test_without_default_polymorphic(self):
        Employee, Engineer, Manager = self.classes(
            "Employee", "Engineer", "Manager"
        )
        (Hacker,) = self.classes("Hacker")
        (employees_table,) = self.tables("employees")
        engineers_table, managers_table = self.tables("engineers", "managers")
        (hackers_table,) = self.tables("hackers")

        pjoin = polymorphic_union(
            {
                "employee": employees_table,
                "manager": managers_table,
                "engineer": engineers_table,
                "hacker": hackers_table,
            },
            "type",
            "pjoin",
        )
        pjoin2 = polymorphic_union(
            {"engineer": engineers_table, "hacker": hackers_table},
            "type",
            "pjoin2",
        )
        employee_mapper = self.mapper_registry.map_imperatively(
            Employee, employees_table, polymorphic_identity="employee"
        )
        self.mapper_registry.map_imperatively(
            Manager,
            managers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="manager",
        )
        engineer_mapper = self.mapper_registry.map_imperatively(
            Engineer,
            engineers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="engineer",
        )
        self.mapper_registry.map_imperatively(
            Hacker,
            hackers_table,
            inherits=engineer_mapper,
            concrete=True,
            polymorphic_identity="hacker",
        )
        session = fixture_session()
        jdoe = Employee("Jdoe")
        tom = Manager("Tom", "knows how to manage things")
        jerry = Engineer("Jerry", "knows how to program")
        hacker = Hacker("Kurt", "Badass", "knows how to hack")
        session.add_all((jdoe, tom, jerry, hacker))
        session.flush()

        with expect_deprecated_20(with_polymorphic_dep):
            eq_(
                len(
                    session.connection()
                    .execute(
                        session.query(Employee)
                        .with_polymorphic("*", pjoin, pjoin.c.type)
                        .statement
                    )
                    .fetchall()
                ),
                4,
            )
        eq_(session.get(Employee, jdoe.employee_id), jdoe)
        eq_(session.get(Engineer, jerry.employee_id), jerry)
        with expect_deprecated_20(with_polymorphic_dep):
            eq_(
                set(
                    [
                        repr(x)
                        for x in session.query(Employee).with_polymorphic(
                            "*", pjoin, pjoin.c.type
                        )
                    ]
                ),
                set(
                    [
                        "Employee Jdoe",
                        "Engineer Jerry knows how to program",
                        "Manager Tom knows how to manage things",
                        "Hacker Kurt 'Badass' knows how to hack",
                    ]
                ),
            )
        eq_(
            set([repr(x) for x in session.query(Manager)]),
            set(["Manager Tom knows how to manage things"]),
        )
        with expect_deprecated_20(with_polymorphic_dep):
            eq_(
                set(
                    [
                        repr(x)
                        for x in session.query(Engineer).with_polymorphic(
                            "*", pjoin2, pjoin2.c.type
                        )
                    ]
                ),
                set(
                    [
                        "Engineer Jerry knows how to program",
                        "Hacker Kurt 'Badass' knows how to hack",
                    ]
                ),
            )
        eq_(
            set([repr(x) for x in session.query(Hacker)]),
            set(["Hacker Kurt 'Badass' knows how to hack"]),
        )

        # test adaption of the column by wrapping the query in a
        # subquery

        with testing.expect_deprecated(
            r"The Query.from_self\(\) method", with_polymorphic_dep
        ):
            eq_(
                len(
                    session.connection()
                    .execute(
                        session.query(Engineer)
                        .with_polymorphic("*", pjoin2, pjoin2.c.type)
                        .from_self()
                        .statement
                    )
                    .fetchall()
                ),
                2,
            )
        with testing.expect_deprecated(
            r"The Query.from_self\(\) method", with_polymorphic_dep
        ):
            eq_(
                set(
                    [
                        repr(x)
                        for x in session.query(Engineer)
                        .with_polymorphic("*", pjoin2, pjoin2.c.type)
                        .from_self()
                    ]
                ),
                set(
                    [
                        "Engineer Jerry knows how to program",
                        "Hacker Kurt 'Badass' knows how to hack",
                    ]
                ),
            )
Example #11
0
# just Collections that have additional data.

# :C0103: Tables and mappers are constants but SQLAlchemy/TurboGears convention
# is not to name them with all uppercase
# pylint: disable-msg=C0103
CollectionTable = Table('collection', metadata, autoload=True)
BranchTable = Table('branch', metadata, autoload=True)
ReposTable = Table('repos', metadata, autoload=True)


CollectionJoin = polymorphic_union (
        {'b' : select((CollectionTable.join(
            BranchTable, CollectionTable.c.id == BranchTable.c.collectionid),)),
         'c' : select((CollectionTable,),
             not_(CollectionTable.c.id.in_(select(
                 (CollectionTable.c.id,),
                 CollectionTable.c.id == BranchTable.c.collectionid)
             )))
         },
        'kind', 'CollectionJoin'
        )
#
# CollectionTable that shows number of packages in a collection
#
CollectionPackageTable = Table('collectionpackage', metadata,
        Column('id', Integer, primary_key=True),
        Column('statuscode', Integer,
            ForeignKey('collectionstatuscode.statuscodeid')),
        autoload=True)

#
Example #12
0
        self.manager_data = manager_data
    def __repr__(self):
        return self.__class__.__name__ + " " + \
                    self.name + " " +  self.manager_data

class Engineer(Employee):
    def __init__(self, name, engineer_info):
        self.name = name
        self.engineer_info = engineer_info
    def __repr__(self):
        return self.__class__.__name__ + " " + \
                    self.name + " " +  self.engineer_info


pjoin = polymorphic_union({
    'manager':managers_table,
    'engineer':engineers_table
}, 'type', 'pjoin')

employee_mapper = mapper(Employee, pjoin, polymorphic_on=pjoin.c.type)
manager_mapper = mapper(Manager, managers_table,
                        inherits=employee_mapper, concrete=True,
                        polymorphic_identity='manager')
engineer_mapper = mapper(Engineer, engineers_table,
                         inherits=employee_mapper, concrete=True,
                         polymorphic_identity='engineer')


session = sessionmaker(engine)()

m1 = Manager("pointy haired boss", "manager1")
e1 = Engineer("wally", "engineer1")
Example #13
0
def initMappings():
    a = sqlalchemy    
    s = Schema
    
    def eventstampedMapper(class_, local_table, **kwargs):
        props = kwargs.setdefault('properties', {})
        props['creationEvent'] = orm.relation(Event)
        props['eventId'] = local_table.c.event_id
        return orm.mapper(class_, local_table, **kwargs)
    
    orm.mapper(Event, s.event, properties={
        'eventId' : s.event.c.event_id,
        'eventTimestamp' : s.event.c.event_timestamp,
        })

    
    transactionMapper = eventstampedMapper(
        Transaction, s.statementItem, properties={
            'date' : s.statementItem.c.dtposted,
            'amount' : s.statementItem.c.trnamt,
            })

    isLikelyInvoiceable = a.exists([1],
        s.statementItem.c.memo.ilike(s.likelyInvoiceable.c.pattern)) \
        .correlate(s.statementItem) \
        .label('isLikelyInvoiceable')
    isInvoiceable = a.exists([1],
        s.statementItem.c.fitid == s.invoiceableItem.c.fitid) \
        .label('isInvoiceable')
    isLikelyPayment = ((s.statementItem.c.trnamt > 0) &
        (s.statementItem.c.trnamt <= MAXIMUM_LIKELY_PAYMENT)) \
        .label('isLikelyPayment')
    isPayment = a.exists([1],
        s.statementItem.c.fitid == s.paymentStatementEvidence.c.fitid) \
        .label('isPayment')

    transactionListSelect = a.select([
        s.statementItem,
        isLikelyInvoiceable,
        isInvoiceable,
        isLikelyPayment,
        isPayment,
        ]).alias('transactionSelect')
    
    global transactionListMapper
    transactionListMapper = orm.mapper(Transaction,
        transactionListSelect, properties={
            'date' : s.statementItem.c.dtposted,
            'amount' : s.statementItem.c.trnamt,
            },
        non_primary=True)

    eventstampedMapper(ImportedStatement, s.importedStatement, properties={
        'beginDate' : s.importedStatement.c.begin_date,
        'endDate' : s.importedStatement.c.end_date,
        })


    orm.mapper(Person, s.person, properties={
        'personId' : s.person.c.person_id,
        'givenName' : s.person.c.given_name,
        'familyName' : s.person.c.family_name,
        'tenancies' : orm.relation(Tenancy, backref='person', cascade='all, delete-orphan'),
        'payments' : orm.relation(Payment, backref='personFrom', cascade='all, delete-orphan'),
        'invoices' : orm.relation(Invoice, backref='personTo', cascade='all, delete-orphan'),
        })

    eventstampedMapper(Tenancy, s.personTenancy, properties={
        'tenancyId' : s.personTenancy.c.tenancy_id,
        'personId' : s.personTenancy.c.person_id,
        'dateMovedIn' : s.personTenancy.c.date_moved_in,
        'dateMovedOut' : s.personTenancy.c.date_moved_out,
        })
    

    paymentJoin = orm.polymorphic_union(
        {
            'paymentWithStatementEvidence' : s.personPayment.join(s.paymentStatementEvidence),
            'paymentWithOtherEvidence' : s.personPayment.join(s.paymentOtherEvidence),
        }, None, 'paymentjoin')
    
    paymentMapper = eventstampedMapper(Payment, s.personPayment,
        polymorphic_on=s.personPayment.c.evidence_type,
        properties={
            'paymentId' : s.personPayment.c.payment_id,
            'personId' : s.personPayment.c.person_id,
            'paymentDate' : s.personPayment.c.payment_date,
            'evidenceType' : s.personPayment.c.evidence_type,
            })
    orm.mapper(PaymentWithStatementEvidence, s.paymentStatementEvidence,
         inherits=paymentMapper, polymorphic_identity='statement',
         properties={ 'transaction' : orm.relation(Transaction) })
    orm.mapper(PaymentWithOtherEvidence, s.paymentOtherEvidence,
         inherits=paymentMapper, polymorphic_identity='other')


    eventstampedMapper(InvoiceableItem, s.invoiceableItem, properties={
         'transaction' : orm.relation(Transaction),
         })

    eventstampedMapper(Invoice, s.personInvoice, properties={
        'invoiceId' : s.personInvoice.c.invoice_id,
        'personId' : s.personInvoice.c.person_id,
        'invoiceDate' : s.personInvoice.c.invoice_date,
        'amount' : s.personInvoice.c.amount,
        })

    orm.mapper(LikelyInvoiceable, s.likelyInvoiceable)

    orm.compile_mappers()
                                  productFilter=release.product,
                                  versionFilter=release.version,
                                  searchOtherShipped=True)
            if similar:
                # The release has been marked as shipped (this build or an other)
                # Store this information to disable the button to avoid two builds of
                # the same version marked as shipped
                release.ReleaseMarkedAsShipped = True

    return releases


release_union = polymorphic_union(
    {
        'firefox': FirefoxRelease.__table__,
        'fennec': FennecRelease.__table__,
        'devedition': DeveditionRelease.__table__,
        'thunderbird': ThunderbirdRelease.__table__
    }, 'product', 'release')


class ProductReleasesView(object):
    view = release_union

    @classmethod
    def getOrderByList(cls, orderByDict):
        lst = []
        for k, v in orderByDict.iteritems():
            column = getattr(cls.view.c, k)
            direction = getattr(column, v)
            lst.append(direction())
Example #15
0
            # Search if we don't have a build (same version + product) already shipped
            similar = getReleases(shipped=True, productFilter=release.product,
                                  versionFilter=release.version,
                                  searchOtherShipped=True)
            if similar:
                # The release has been marked as shipped (this build or an other)
                # Store this information to disable the button to avoid two builds of
                # the same version marked as shipped
                release.ReleaseMarkedAsShipped = True

    return releases


release_union = polymorphic_union({
    'firefox': FirefoxRelease.__table__,
    'fennec': FennecRelease.__table__,
    'devedition': DeveditionRelease.__table__,
    'thunderbird': ThunderbirdRelease.__table__
}, 'product', 'release')


class ProductReleasesView(object):
    view = release_union

    @classmethod
    def getOrderByList(cls, orderByDict):
        lst = []
        for k, v in orderByDict.iteritems():
            column = getattr(cls.view.c, k)
            direction = getattr(column, v)
            lst.append(direction())
Example #16
0
    def test_relationship(self):
        Employee, Engineer, Manager = self.classes(
            "Employee", "Engineer", "Manager"
        )
        (Company,) = self.classes("Company")
        (companies,) = self.tables("companies")
        engineers_table, managers_table = self.tables("engineers", "managers")

        pjoin = polymorphic_union(
            {"manager": managers_table, "engineer": engineers_table},
            "type",
            "pjoin",
        )
        self.mapper_registry.map_imperatively(
            Company,
            companies,
            properties={"employees": relationship(Employee)},
        )
        employee_mapper = self.mapper_registry.map_imperatively(
            Employee, pjoin, polymorphic_on=pjoin.c.type
        )
        self.mapper_registry.map_imperatively(
            Manager,
            managers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="manager",
        )
        self.mapper_registry.map_imperatively(
            Engineer,
            engineers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="engineer",
        )
        session = fixture_session()
        c = Company()
        c.employees.append(Manager("Sally", "knows how to manage things"))
        c.employees.append(Engineer("Karina", "knows how to hack"))
        session.add(c)
        session.flush()
        session.expunge_all()

        def go():
            c2 = session.get(Company, c.id)
            assert set([repr(x) for x in c2.employees]) == set(
                [
                    "Engineer Karina knows how to hack",
                    "Manager Sally knows how to manage things",
                ]
            )

        self.assert_sql_count(testing.db, go, 2)
        session.expunge_all()

        def go():
            c2 = session.get(
                Company, c.id, options=[joinedload(Company.employees)]
            )
            assert set([repr(x) for x in c2.employees]) == set(
                [
                    "Engineer Karina knows how to hack",
                    "Manager Sally knows how to manage things",
                ]
            )

        self.assert_sql_count(testing.db, go, 1)
Example #17
0
    def two_pjoin_fixture(self):
        Employee, Engineer, Manager = self.classes(
            "Employee", "Engineer", "Manager"
        )
        (Hacker,) = self.classes("Hacker")
        (employees_table,) = self.tables("employees")
        engineers_table, managers_table = self.tables("engineers", "managers")
        (hackers_table,) = self.tables("hackers")

        pjoin = polymorphic_union(
            {
                "employee": employees_table,
                "manager": managers_table,
                "engineer": engineers_table,
                "hacker": hackers_table,
            },
            "type",
            "pjoin",
        )
        pjoin2 = polymorphic_union(
            {"engineer": engineers_table, "hacker": hackers_table},
            "type",
            "pjoin2",
        )
        employee_mapper = self.mapper_registry.map_imperatively(
            Employee, employees_table, polymorphic_identity="employee"
        )
        self.mapper_registry.map_imperatively(
            Manager,
            managers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="manager",
        )
        engineer_mapper = self.mapper_registry.map_imperatively(
            Engineer,
            engineers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="engineer",
        )
        self.mapper_registry.map_imperatively(
            Hacker,
            hackers_table,
            inherits=engineer_mapper,
            concrete=True,
            polymorphic_identity="hacker",
        )

        session = fixture_session(expire_on_commit=False)
        jdoe = Employee("Jdoe")
        sally = Manager("Sally", "knows how to manage things")
        jenn = Engineer("Jenn", "knows how to program")
        hacker = Hacker("Karina", "Badass", "knows how to hack")
        session.add_all((jdoe, sally, jenn, hacker))
        session.commit()

        return (
            session,
            Employee,
            Engineer,
            Manager,
            Hacker,
            pjoin,
            pjoin2,
            jdoe,
            sally,
            jenn,
            hacker,
        )
Example #18
0
    def test_multi_level_with_base(self):
        Employee, Engineer, Manager = self.classes(
            "Employee", "Engineer", "Manager"
        )
        employees_table, engineers_table, managers_table = self.tables(
            "employees", "engineers", "managers"
        )
        (hackers_table,) = self.tables("hackers")
        (Hacker,) = self.classes("Hacker")

        pjoin = polymorphic_union(
            {
                "employee": employees_table,
                "manager": managers_table,
                "engineer": engineers_table,
                "hacker": hackers_table,
            },
            "type",
            "pjoin",
        )
        pjoin2 = polymorphic_union(
            {"engineer": engineers_table, "hacker": hackers_table},
            "type",
            "pjoin2",
        )
        employee_mapper = self.mapper_registry.map_imperatively(
            Employee,
            employees_table,
            with_polymorphic=("*", pjoin),
            polymorphic_on=pjoin.c.type,
        )
        self.mapper_registry.map_imperatively(
            Manager,
            managers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="manager",
        )
        engineer_mapper = self.mapper_registry.map_imperatively(
            Engineer,
            engineers_table,
            with_polymorphic=("*", pjoin2),
            polymorphic_on=pjoin2.c.type,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="engineer",
        )
        self.mapper_registry.map_imperatively(
            Hacker,
            hackers_table,
            inherits=engineer_mapper,
            concrete=True,
            polymorphic_identity="hacker",
        )
        session = fixture_session()
        sally = Manager("Sally", "knows how to manage things")
        jenn = Engineer("Jenn", "knows how to program")
        hacker = Hacker("Karina", "Badass", "knows how to hack")
        session.add_all((sally, jenn, hacker))
        session.flush()

        def go():
            eq_(jenn.name, "Jenn")
            eq_(hacker.nickname, "Badass")

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

        # check that we aren't getting a cartesian product in the raw
        # SQL. this requires that Engineer's polymorphic discriminator
        # is not rendered in the statement which is only against
        # Employee's "pjoin"

        assert (
            len(
                session.connection()
                .execute(session.query(Employee).statement)
                .fetchall()
            )
            == 3
        )
        assert set([repr(x) for x in session.query(Employee)]) == set(
            [
                "Engineer Jenn knows how to program",
                "Manager Sally knows how to manage things",
                "Hacker Karina 'Badass' knows how to hack",
            ]
        )
        assert set([repr(x) for x in session.query(Manager)]) == set(
            ["Manager Sally knows how to manage things"]
        )
        assert set([repr(x) for x in session.query(Engineer)]) == set(
            [
                "Engineer Jenn knows how to program",
                "Hacker Karina 'Badass' knows how to hack",
            ]
        )
        assert set([repr(x) for x in session.query(Hacker)]) == set(
            ["Hacker Karina 'Badass' knows how to hack"]
        )
Example #19
0
    def test_multi_level_no_base_w_hybrid(self):
        Employee, Engineer, Manager = self.classes(
            "Employee", "Engineer", "Manager"
        )
        (Hacker,) = self.classes("Hacker")
        engineers_table, managers_table = self.tables("engineers", "managers")
        (hackers_table,) = self.tables("hackers")

        pjoin = polymorphic_union(
            {
                "manager": managers_table,
                "engineer": engineers_table,
                "hacker": hackers_table,
            },
            "type",
            "pjoin",
        )

        test_calls = mock.Mock()

        class ManagerWHybrid(Employee):
            def __init__(self, name, manager_data):
                self.name = name
                self.manager_data = manager_data

            @hybrid_property
            def engineer_info(self):
                test_calls.engineer_info_instance()
                return self.manager_data

            @engineer_info.expression
            def engineer_info(cls):
                test_calls.engineer_info_class()
                return cls.manager_data

        employee_mapper = self.mapper_registry.map_imperatively(
            Employee, pjoin, polymorphic_on=pjoin.c.type
        )
        self.mapper_registry.map_imperatively(
            ManagerWHybrid,
            managers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="manager",
        )
        self.mapper_registry.map_imperatively(
            Engineer,
            engineers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="engineer",
        )

        session = fixture_session()
        sally = ManagerWHybrid("Sally", "mgrdata")

        # mapping did not impact the engineer_info
        # hybrid in any way
        eq_(test_calls.mock_calls, [])

        eq_(sally.engineer_info, "mgrdata")
        eq_(test_calls.mock_calls, [mock.call.engineer_info_instance()])

        session.add(sally)
        session.commit()

        session.close()

        Sally = (
            session.query(ManagerWHybrid)
            .filter(ManagerWHybrid.engineer_info == "mgrdata")
            .one()
        )
        eq_(
            test_calls.mock_calls,
            [
                mock.call.engineer_info_instance(),
                mock.call.engineer_info_class(),
            ],
        )
        eq_(Sally.engineer_info, "mgrdata")
Example #20
0
    def test_multi_level_no_base(self):
        Employee, Engineer, Manager = self.classes(
            "Employee", "Engineer", "Manager"
        )
        (Hacker,) = self.classes("Hacker")
        engineers_table, managers_table = self.tables("engineers", "managers")
        (hackers_table,) = self.tables("hackers")

        pjoin = polymorphic_union(
            {
                "manager": managers_table,
                "engineer": engineers_table,
                "hacker": hackers_table,
            },
            "type",
            "pjoin",
        )
        pjoin2 = polymorphic_union(
            {"engineer": engineers_table, "hacker": hackers_table},
            "type",
            "pjoin2",
        )
        employee_mapper = self.mapper_registry.map_imperatively(
            Employee, pjoin, polymorphic_on=pjoin.c.type
        )
        self.mapper_registry.map_imperatively(
            Manager,
            managers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="manager",
        )
        engineer_mapper = self.mapper_registry.map_imperatively(
            Engineer,
            engineers_table,
            with_polymorphic=("*", pjoin2),
            polymorphic_on=pjoin2.c.type,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="engineer",
        )
        self.mapper_registry.map_imperatively(
            Hacker,
            hackers_table,
            inherits=engineer_mapper,
            concrete=True,
            polymorphic_identity="hacker",
        )
        session = fixture_session()
        sally = Manager("Sally", "knows how to manage things")

        assert_raises_message(
            AttributeError,
            "does not implement attribute .?'type' at the instance level.",
            setattr,
            sally,
            "type",
            "sometype",
        )

        jenn = Engineer("Jenn", "knows how to program")
        hacker = Hacker("Karina", "Badass", "knows how to hack")

        assert_raises_message(
            AttributeError,
            "does not implement attribute .?'type' at the instance level.",
            setattr,
            hacker,
            "type",
            "sometype",
        )

        session.add_all((sally, jenn, hacker))
        session.flush()

        # ensure "readonly" on save logic didn't pollute the
        # expired_attributes collection

        assert (
            "nickname"
            not in attributes.instance_state(jenn).expired_attributes
        )
        assert "name" not in attributes.instance_state(jenn).expired_attributes
        assert (
            "name" not in attributes.instance_state(hacker).expired_attributes
        )
        assert (
            "nickname"
            not in attributes.instance_state(hacker).expired_attributes
        )

        def go():
            eq_(jenn.name, "Jenn")
            eq_(hacker.nickname, "Badass")

        self.assert_sql_count(testing.db, go, 0)
        session.expunge_all()
        assert (
            repr(
                session.query(Employee).filter(Employee.name == "Sally").one()
            )
            == "Manager Sally knows how to manage things"
        )
        assert (
            repr(session.query(Manager).filter(Manager.name == "Sally").one())
            == "Manager Sally knows how to manage things"
        )
        assert set([repr(x) for x in session.query(Employee).all()]) == set(
            [
                "Engineer Jenn knows how to program",
                "Manager Sally knows how to manage things",
                "Hacker Karina 'Badass' knows how to hack",
            ]
        )
        assert set([repr(x) for x in session.query(Manager).all()]) == set(
            ["Manager Sally knows how to manage things"]
        )
        assert set([repr(x) for x in session.query(Engineer).all()]) == set(
            [
                "Engineer Jenn knows how to program",
                "Hacker Karina 'Badass' knows how to hack",
            ]
        )
        assert set([repr(x) for x in session.query(Hacker).all()]) == set(
            ["Hacker Karina 'Badass' knows how to hack"]
        )
Example #21
0
                                       autoload=True)

logJoin = polymorphic_union(
    {
        'pkglog':
        select((LogTable.join(PackageLogTable, LogTable.c.id
                              == PackageLogTable.c.logid),
                literal_column("'pkglog'").label('kind'))),
        'pkglistlog':
        select((LogTable.join(PackageListingLogTable, LogTable.c.id
                              == PackageListingLogTable.c.logid),
                literal_column("'pkglistlog'").label('kind'))),
        'personpkglistacllog':
        select((LogTable.join(
            PersonPackageListingAclLogTable, LogTable.c.id
            == PersonPackageListingAclLogTable.c.logid),
                literal_column("'personpkglistacllog'").label('kind'))),
        'grouppkglistacllog':
        select((LogTable.join(
            GroupPackageListingAclLogTable, LogTable.c.id
            == GroupPackageListingAclLogTable.c.logid),
                literal_column("'grouppkglistacllog'").label('kind'))),
        'log':
        select((LogTable, literal_column("'log'").label('kind')),
               not_(
                   LogTable.c.id.in_(
                       select((LogTable.c.id, ), LogTable.c.id
                              == PackageListingLogTable.c.logid))))
    }, None)

#
Example #22
0
    def setup_mapper(self):
        '''
        Initializes and assign a mapper to the entity.
        At this point the mapper will usually have no property as they are
        added later.
        '''
        if self.entity.mapper:
            return

        # for now we don't support the "abstract" parent class in a concrete
        # inheritance scenario as demonstrated in
        # sqlalchemy/test/orm/inheritance/concrete.py
        # this should be added along other
        kwargs = {}
        if self.order_by:
            kwargs['order_by'] = self.translate_order_by(self.order_by)

        if self.version_id_col:
            kwargs['version_id_col'] = self.get_column(self.version_id_col)

        if self.inheritance in ('single', 'concrete', 'multi'):
            if self.parent and \
               (self.inheritance != 'concrete' or self.polymorphic):
                # non-polymorphic concrete doesn't need this
                kwargs['inherits'] = self.parent.mapper

            if self.inheritance == 'multi' and self.parent:
                kwargs['inherit_condition'] = self.join_condition

            if self.polymorphic:
                if self.children:
                    if self.inheritance == 'concrete':
                        keys = [(self.identity, self.entity.table)]
                        keys.extend([(child._descriptor.identity, child.table)
                                     for child in self._get_children()])
                        # Having the same alias name for an entity and one of
                        # its child (which is a parent itself) shouldn't cause
                        # any problem because the join shouldn't be used at
                        # the same time. But in reality, some versions of SA
                        # do misbehave on this. Since it doesn't hurt to have
                        # different names anyway, here they go.
                        pjoin = polymorphic_union(
                                    dict(keys), self.polymorphic,
                                    'pjoin_%s' % self.identity)

                        kwargs['with_polymorphic'] = ('*', pjoin)
                        kwargs['polymorphic_on'] = \
                            getattr(pjoin.c, self.polymorphic)
                    elif not self.parent:
                        kwargs['polymorphic_on'] = \
                            self.get_column(self.polymorphic)

                if self.children or self.parent:
                    kwargs['polymorphic_identity'] = self.identity

                if self.parent and self.inheritance == 'concrete':
                    kwargs['concrete'] = True

        if self.parent and self.inheritance == 'single':
            args = []
        else:
            args = [self.entity.table]

        # let user-defined kwargs override Elixir-generated ones, though that's
        # not very usefull since most of them expect Column instances.
        kwargs.update(self.mapper_options)

        #TODO: document this!
        if 'primary_key' in kwargs:
            cols = self.entity.table.c
            kwargs['primary_key'] = [getattr(cols, colname) for
                colname in kwargs['primary_key']]

        # do the mapping
        if self.session is None:
            self.entity.mapper = mapper(self.entity, *args, **kwargs)
        elif isinstance(self.session, ScopedSession):
            session_mapper = session_mapper_factory(self.session)
            self.entity.mapper = session_mapper(self.entity, *args, **kwargs)
        else:
            raise Exception("Failed to map entity '%s' with its table or "
                            "selectable. You can only bind an Entity to a "
                            "ScopedSession object or None for manual session "
                            "management."
                            % self.entity.__name__)
Example #23
0
    def test_multi_level_no_base_w_hybrid(self):
        pjoin = polymorphic_union(
            {
                "manager": managers_table,
                "engineer": engineers_table,
                "hacker": hackers_table,
            },
            "type",
            "pjoin",
        )

        test_calls = mock.Mock()

        class ManagerWHybrid(Employee):
            def __init__(self, name, manager_data):
                self.name = name
                self.manager_data = manager_data

            @hybrid_property
            def engineer_info(self):
                test_calls.engineer_info_instance()
                return self.manager_data

            @engineer_info.expression
            def engineer_info(cls):
                test_calls.engineer_info_class()
                return cls.manager_data

        employee_mapper = mapper(Employee, pjoin, polymorphic_on=pjoin.c.type)
        mapper(
            ManagerWHybrid,
            managers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="manager",
        )
        mapper(
            Engineer,
            engineers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="engineer",
        )

        session = create_session()
        tom = ManagerWHybrid("Tom", "mgrdata")

        # mapping did not impact the engineer_info
        # hybrid in any way
        eq_(test_calls.mock_calls, [])

        eq_(tom.engineer_info, "mgrdata")
        eq_(test_calls.mock_calls, [mock.call.engineer_info_instance()])

        session.add(tom)
        session.flush()

        session.close()

        tom = (
            session.query(ManagerWHybrid)
            .filter(ManagerWHybrid.engineer_info == "mgrdata")
            .one()
        )
        eq_(
            test_calls.mock_calls,
            [
                mock.call.engineer_info_instance(),
                mock.call.engineer_info_class(),
            ],
        )
        eq_(tom.engineer_info, "mgrdata")
    def test_roundtrip(self):
        if with_polymorphic == "unions":
            if include_base:
                person_join = polymorphic_union(
                    {
                        "engineer":
                        people.join(engineers),
                        "manager":
                        people.join(managers),
                        "person":
                        people.select(people.c.type == "person").subquery(),
                    },
                    None,
                    "pjoin",
                )
            else:
                person_join = polymorphic_union(
                    {
                        "engineer": people.join(engineers),
                        "manager": people.join(managers),
                    },
                    None,
                    "pjoin",
                )

            manager_join = people.join(managers).outerjoin(boss)
            person_with_polymorphic = ["*", person_join]
            manager_with_polymorphic = ["*", manager_join]
        elif with_polymorphic == "joins":
            person_join = (people.outerjoin(engineers).outerjoin(
                managers).outerjoin(boss))
            manager_join = people.join(managers).outerjoin(boss)
            person_with_polymorphic = ["*", person_join]
            manager_with_polymorphic = ["*", manager_join]
        elif with_polymorphic == "auto":
            person_with_polymorphic = "*"
            manager_with_polymorphic = "*"
        else:
            person_with_polymorphic = None
            manager_with_polymorphic = None

        if redefine_colprop:
            person_mapper = mapper(
                Person,
                people,
                with_polymorphic=person_with_polymorphic,
                polymorphic_on=people.c.type,
                polymorphic_identity="person",
                properties={"person_name": people.c.name},
            )
        else:
            person_mapper = mapper(
                Person,
                people,
                with_polymorphic=person_with_polymorphic,
                polymorphic_on=people.c.type,
                polymorphic_identity="person",
            )

        mapper(
            Engineer,
            engineers,
            inherits=person_mapper,
            polymorphic_identity="engineer",
        )
        mapper(
            Manager,
            managers,
            inherits=person_mapper,
            with_polymorphic=manager_with_polymorphic,
            polymorphic_identity="manager",
        )

        mapper(Boss, boss, inherits=Manager, polymorphic_identity="boss")

        mapper(
            Company,
            companies,
            properties={
                "employees":
                relationship(
                    Person,
                    lazy=lazy_relationship,
                    cascade="all, delete-orphan",
                    backref="company",
                    order_by=people.c.person_id,
                )
            },
        )

        if redefine_colprop:
            person_attribute_name = "person_name"
        else:
            person_attribute_name = "name"

        employees = [
            Manager(status="AAB",
                    manager_name="manager1",
                    **{person_attribute_name: "pointy haired boss"}),
            Engineer(status="BBA",
                     engineer_name="engineer1",
                     primary_language="java",
                     **{person_attribute_name: "dilbert"}),
        ]
        if include_base:
            employees.append(Person(**{person_attribute_name: "joesmith"}))
        employees += [
            Engineer(status="CGG",
                     engineer_name="engineer2",
                     primary_language="python",
                     **{person_attribute_name: "wally"}),
            Manager(status="ABA",
                    manager_name="manager2",
                    **{person_attribute_name: "jsmith"}),
        ]

        pointy = employees[0]
        jsmith = employees[-1]
        dilbert = employees[1]

        session = create_session()
        c = Company(name="company1")
        c.employees = employees
        session.add(c)

        session.flush()
        session.expunge_all()

        eq_(session.query(Person).get(dilbert.person_id), dilbert)
        session.expunge_all()

        eq_(
            session.query(Person).filter(
                Person.person_id == dilbert.person_id).one(),
            dilbert,
        )
        session.expunge_all()

        def go():
            cc = session.query(Company).get(c.company_id)
            eq_(cc.employees, employees)

        if not lazy_relationship:
            if with_polymorphic != "none":
                self.assert_sql_count(testing.db, go, 1)
            else:
                self.assert_sql_count(testing.db, go, 5)

        else:
            if with_polymorphic != "none":
                self.assert_sql_count(testing.db, go, 2)
            else:
                self.assert_sql_count(testing.db, go, 6)

        # test selecting from the query, using the base
        # mapped table (people) as the selection criterion.
        # in the case of the polymorphic Person query,
        # the "people" selectable should be adapted to be "person_join"
        eq_(
            session.query(Person).filter(
                getattr(Person, person_attribute_name) == "dilbert").first(),
            dilbert,
        )

        assert (session.query(Person).filter(
            getattr(Person, person_attribute_name) ==
            "dilbert").first().person_id)

        eq_(
            session.query(Engineer).filter(
                getattr(Person, person_attribute_name) == "dilbert").first(),
            dilbert,
        )

        # test selecting from the query, joining against
        # an alias of the base "people" table.  test that
        # the "palias" alias does *not* get sucked up
        # into the "person_join" conversion.
        palias = people.alias("palias")
        dilbert = session.query(Person).get(dilbert.person_id)
        is_(
            dilbert,
            session.query(Person).filter(
                (palias.c.name == "dilbert")
                & (palias.c.person_id == Person.person_id)).first(),
        )
        is_(
            dilbert,
            session.query(Engineer).filter(
                (palias.c.name == "dilbert")
                & (palias.c.person_id == Person.person_id)).first(),
        )
        is_(
            dilbert,
            session.query(Person).filter(
                (Engineer.engineer_name == "engineer1")
                & (engineers.c.person_id == people.c.person_id)).first(),
        )
        is_(
            dilbert,
            session.query(Engineer).filter(
                Engineer.engineer_name == "engineer1")[0],
        )

        session.flush()
        session.expunge_all()

        def go():
            session.query(Person).filter(
                getattr(Person, person_attribute_name) == "dilbert").first()

        self.assert_sql_count(testing.db, go, 1)
        session.expunge_all()
        dilbert = (session.query(Person).filter(
            getattr(Person, person_attribute_name) == "dilbert").first())

        def go():
            # assert that only primary table is queried for
            # already-present-in-session
            d = (session.query(Person).filter(
                getattr(Person, person_attribute_name) == "dilbert").first())

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

        # test standalone orphans
        daboss = Boss(status="BBB",
                      manager_name="boss",
                      golf_swing="fore",
                      **{person_attribute_name: "daboss"})
        session.add(daboss)
        assert_raises(sa_exc.DBAPIError, session.flush)

        c = session.query(Company).first()
        daboss.company = c
        manager_list = [e for e in c.employees if isinstance(e, Manager)]
        session.flush()
        session.expunge_all()

        eq_(
            session.query(Manager).order_by(Manager.person_id).all(),
            manager_list,
        )
        c = session.query(Company).first()

        session.delete(c)
        session.flush()

        eq_(select([func.count("*")]).select_from(people).scalar(), 0)
Example #25
0
    def test_without_default_polymorphic(self):
        pjoin = polymorphic_union(
            {
                "employee": employees_table,
                "manager": managers_table,
                "engineer": engineers_table,
                "hacker": hackers_table,
            },
            "type",
            "pjoin",
        )
        pjoin2 = polymorphic_union(
            {"engineer": engineers_table, "hacker": hackers_table},
            "type",
            "pjoin2",
        )
        employee_mapper = mapper(
            Employee, employees_table, polymorphic_identity="employee"
        )
        manager_mapper = mapper(
            Manager,
            managers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="manager",
        )
        engineer_mapper = mapper(
            Engineer,
            engineers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="engineer",
        )
        hacker_mapper = mapper(
            Hacker,
            hackers_table,
            inherits=engineer_mapper,
            concrete=True,
            polymorphic_identity="hacker",
        )
        session = create_session()
        jdoe = Employee("Jdoe")
        tom = Manager("Tom", "knows how to manage things")
        jerry = Engineer("Jerry", "knows how to program")
        hacker = Hacker("Kurt", "Badass", "knows how to hack")
        session.add_all((jdoe, tom, jerry, hacker))
        session.flush()
        eq_(
            len(
                testing.db.execute(
                    session.query(Employee)
                    .with_polymorphic("*", pjoin, pjoin.c.type)
                    .with_labels()
                    .statement
                ).fetchall()
            ),
            4,
        )
        eq_(session.query(Employee).get(jdoe.employee_id), jdoe)
        eq_(session.query(Engineer).get(jerry.employee_id), jerry)
        eq_(
            set(
                [
                    repr(x)
                    for x in session.query(Employee).with_polymorphic(
                        "*", pjoin, pjoin.c.type
                    )
                ]
            ),
            set(
                [
                    "Employee Jdoe",
                    "Engineer Jerry knows how to program",
                    "Manager Tom knows how to manage things",
                    "Hacker Kurt 'Badass' knows how to hack",
                ]
            ),
        )
        eq_(
            set([repr(x) for x in session.query(Manager)]),
            set(["Manager Tom knows how to manage things"]),
        )
        eq_(
            set(
                [
                    repr(x)
                    for x in session.query(Engineer).with_polymorphic(
                        "*", pjoin2, pjoin2.c.type
                    )
                ]
            ),
            set(
                [
                    "Engineer Jerry knows how to program",
                    "Hacker Kurt 'Badass' knows how to hack",
                ]
            ),
        )
        eq_(
            set([repr(x) for x in session.query(Hacker)]),
            set(["Hacker Kurt 'Badass' knows how to hack"]),
        )

        # test adaption of the column by wrapping the query in a
        # subquery

        eq_(
            len(
                testing.db.execute(
                    session.query(Engineer)
                    .with_polymorphic("*", pjoin2, pjoin2.c.type)
                    .from_self()
                    .statement
                ).fetchall()
            ),
            2,
        )
        eq_(
            set(
                [
                    repr(x)
                    for x in session.query(Engineer)
                    .with_polymorphic("*", pjoin2, pjoin2.c.type)
                    .from_self()
                ]
            ),
            set(
                [
                    "Engineer Jerry knows how to program",
                    "Hacker Kurt 'Badass' knows how to hack",
                ]
            ),
        )
Example #26
0
logJoin = polymorphic_union(
    {
        "pkglog": select(
            (
                LogTable.join(PackageLogTable, LogTable.c.id == PackageLogTable.c.logid),
                literal_column("'pkglog'").label("kind"),
            )
        ),
        "pkglistlog": select(
            (
                LogTable.join(PackageListingLogTable, LogTable.c.id == PackageListingLogTable.c.logid),
                literal_column("'pkglistlog'").label("kind"),
            )
        ),
        "personpkglistacllog": select(
            (
                LogTable.join(
                    PersonPackageListingAclLogTable, LogTable.c.id == PersonPackageListingAclLogTable.c.logid
                ),
                literal_column("'personpkglistacllog'").label("kind"),
            )
        ),
        "grouppkglistacllog": select(
            (
                LogTable.join(GroupPackageListingAclLogTable, LogTable.c.id == GroupPackageListingAclLogTable.c.logid),
                literal_column("'grouppkglistacllog'").label("kind"),
            )
        ),
        "log": select(
            (LogTable, literal_column("'log'").label("kind")),
            not_(LogTable.c.id.in_(select((LogTable.c.id,), LogTable.c.id == PackageListingLogTable.c.logid))),
        ),
    },
    None,
)
Example #27
0
    def test_polymorphic_backref(self):
        """test multiple backrefs to the same polymorphically-loading
        attribute."""

        A, C, B, c_table, b_table, a_table, Dest, dest_table = (
            self.classes.A,
            self.classes.C,
            self.classes.B,
            self.tables.c_table,
            self.tables.b_table,
            self.tables.a_table,
            self.classes.Dest,
            self.tables.dest_table,
        )

        ajoin = polymorphic_union(
            {"a": a_table, "b": b_table, "c": c_table}, "type", "ajoin"
        )
        mapper(
            A,
            a_table,
            with_polymorphic=("*", ajoin),
            polymorphic_on=ajoin.c.type,
            polymorphic_identity="a",
            properties={
                "some_dest": relationship(Dest, back_populates="many_a")
            },
        )
        mapper(
            B,
            b_table,
            inherits=A,
            concrete=True,
            polymorphic_identity="b",
            properties={
                "some_dest": relationship(Dest, back_populates="many_a")
            },
        )

        mapper(
            C,
            c_table,
            inherits=A,
            concrete=True,
            polymorphic_identity="c",
            properties={
                "some_dest": relationship(Dest, back_populates="many_a")
            },
        )

        mapper(
            Dest,
            dest_table,
            properties={
                "many_a": relationship(
                    A, back_populates="some_dest", order_by=ajoin.c.id
                )
            },
        )

        sess = sessionmaker()()
        dest1 = Dest(name="c1")
        dest2 = Dest(name="c2")
        a1 = A(some_dest=dest1, aname="a1", id=1)
        a2 = A(some_dest=dest2, aname="a2", id=2)
        b1 = B(some_dest=dest1, bname="b1", id=3)
        b2 = B(some_dest=dest1, bname="b2", id=4)
        c1 = C(some_dest=dest1, cname="c1", id=5)
        c2 = C(some_dest=dest2, cname="c2", id=6)

        eq_([a2, c2], dest2.many_a)
        eq_([a1, b1, b2, c1], dest1.many_a)
        sess.add_all([dest1, dest2])
        sess.commit()

        assert sess.query(Dest).filter(Dest.many_a.contains(a2)).one() is dest2
        assert sess.query(Dest).filter(Dest.many_a.contains(b1)).one() is dest1
        assert sess.query(Dest).filter(Dest.many_a.contains(c2)).one() is dest2

        eq_(dest2.many_a, [a2, c2])
        eq_(dest1.many_a, [a1, b1, b2, c1])
        sess.expire_all()

        def go():
            eq_(
                [
                    Dest(
                        many_a=[
                            A(aname="a1"),
                            B(bname="b1"),
                            B(bname="b2"),
                            C(cname="c1"),
                        ]
                    ),
                    Dest(many_a=[A(aname="a2"), C(cname="c2")]),
                ],
                sess.query(Dest)
                .options(joinedload(Dest.many_a))
                .order_by(Dest.id)
                .all(),
            )

        self.assert_sql_count(testing.db, go, 1)
Example #28
0
    def _setup_mapping(self, use_unions, use_joins):
        (
            Publication,
            Issue,
            Location,
            LocationName,
            PageSize,
            Magazine,
            Page,
            MagazinePage,
            ClassifiedPage,
        ) = self.classes(
            "Publication",
            "Issue",
            "Location",
            "LocationName",
            "PageSize",
            "Magazine",
            "Page",
            "MagazinePage",
            "ClassifiedPage",
        )
        mapper(Publication, self.tables.publication)

        mapper(
            Issue,
            self.tables.issue,
            properties={
                "publication":
                relationship(
                    Publication,
                    backref=backref("issues", cascade="all, delete-orphan"),
                )
            },
        )

        mapper(LocationName, self.tables.location_name)

        mapper(
            Location,
            self.tables.location,
            properties={
                "issue":
                relationship(
                    Issue,
                    backref=backref(
                        "locations",
                        lazy="joined",
                        cascade="all, delete-orphan",
                    ),
                ),
                "name":
                relationship(LocationName),
            },
        )

        mapper(PageSize, self.tables.page_size)

        mapper(
            Magazine,
            self.tables.magazine,
            properties={
                "location":
                relationship(Location,
                             backref=backref("magazine", uselist=False)),
                "size":
                relationship(PageSize),
            },
        )

        if use_unions:
            page_join = polymorphic_union(
                {
                    "m":
                    self.tables.page.join(self.tables.magazine_page),
                    "c":
                    self.tables.page.join(self.tables.magazine_page).join(
                        self.tables.classified_page),
                    "p":
                    self.tables.page.select().where(
                        self.tables.page.c.type == "p").subquery(),
                },
                None,
                "page_join",
            )
            page_mapper = mapper(
                Page,
                self.tables.page,
                with_polymorphic=("*", page_join),
                polymorphic_on=page_join.c.type,
                polymorphic_identity="p",
            )
        elif use_joins:
            page_join = self.tables.page.outerjoin(
                self.tables.magazine_page).outerjoin(
                    self.tables.classified_page)
            page_mapper = mapper(
                Page,
                self.tables.page,
                with_polymorphic=("*", page_join),
                polymorphic_on=self.tables.page.c.type,
                polymorphic_identity="p",
            )
        else:
            page_mapper = mapper(
                Page,
                self.tables.page,
                polymorphic_on=self.tables.page.c.type,
                polymorphic_identity="p",
            )

        if use_unions:
            magazine_join = polymorphic_union(
                {
                    "m":
                    self.tables.page.join(self.tables.magazine_page),
                    "c":
                    self.tables.page.join(self.tables.magazine_page).join(
                        self.tables.classified_page),
                },
                None,
                "page_join",
            )
            magazine_page_mapper = mapper(
                MagazinePage,
                self.tables.magazine_page,
                with_polymorphic=("*", magazine_join),
                inherits=page_mapper,
                polymorphic_identity="m",
                properties={
                    "magazine":
                    relationship(
                        Magazine,
                        backref=backref("pages",
                                        order_by=magazine_join.c.page_no),
                    )
                },
            )
        elif use_joins:
            magazine_join = self.tables.page.join(
                self.tables.magazine_page).outerjoin(
                    self.tables.classified_page)
            magazine_page_mapper = mapper(
                MagazinePage,
                self.tables.magazine_page,
                with_polymorphic=("*", magazine_join),
                inherits=page_mapper,
                polymorphic_identity="m",
                properties={
                    "magazine":
                    relationship(
                        Magazine,
                        backref=backref("pages",
                                        order_by=self.tables.page.c.page_no),
                    )
                },
            )
        else:
            magazine_page_mapper = mapper(
                MagazinePage,
                self.tables.magazine_page,
                inherits=page_mapper,
                polymorphic_identity="m",
                properties={
                    "magazine":
                    relationship(
                        Magazine,
                        backref=backref("pages",
                                        order_by=self.tables.page.c.page_no),
                    )
                },
            )

        mapper(
            ClassifiedPage,
            self.tables.classified_page,
            inherits=magazine_page_mapper,
            polymorphic_identity="c",
            primary_key=[self.tables.page.c.id],
        )
Example #29
0
    def test_roundtrip(self):
        publication_mapper = mapper(Publication, self.tables.publication)

        issue_mapper = mapper(
            Issue,
            self.tables.issue,
            properties={
                "publication": relationship(
                    Publication,
                    backref=backref("issues", cascade="all, delete-orphan"),
                )
            },
        )

        location_name_mapper = mapper(LocationName, self.tables.location_name)

        location_mapper = mapper(
            Location,
            self.tables.location,
            properties={
                "issue": relationship(
                    Issue,
                    backref=backref(
                        "locations",
                        lazy="joined",
                        cascade="all, delete-orphan",
                    ),
                ),
                "_name": relationship(LocationName),
            },
        )

        page_size_mapper = mapper(PageSize, self.tables.page_size)

        magazine_mapper = mapper(
            Magazine,
            self.tables.magazine,
            properties={
                "location": relationship(
                    Location, backref=backref("magazine", uselist=False)
                ),
                "size": relationship(PageSize),
            },
        )

        if use_unions:
            page_join = polymorphic_union(
                {
                    "m": self.tables.page.join(self.tables.magazine_page),
                    "c": self.tables.page.join(self.tables.magazine_page).join(
                        self.tables.classified_page
                    ),
                    "p": self.tables.page.select(
                        self.tables.page.c.type == "p"
                    ).subquery(),
                },
                None,
                "page_join",
            )
            page_mapper = mapper(
                Page,
                self.tables.page,
                with_polymorphic=("*", page_join),
                polymorphic_on=page_join.c.type,
                polymorphic_identity="p",
            )
        elif use_joins:
            page_join = self.tables.page.outerjoin(
                self.tables.magazine_page
            ).outerjoin(self.tables.classified_page)
            page_mapper = mapper(
                Page,
                self.tables.page,
                with_polymorphic=("*", page_join),
                polymorphic_on=self.tables.page.c.type,
                polymorphic_identity="p",
            )
        else:
            page_mapper = mapper(
                Page,
                self.tables.page,
                polymorphic_on=self.tables.page.c.type,
                polymorphic_identity="p",
            )

        if use_unions:
            magazine_join = polymorphic_union(
                {
                    "m": self.tables.page.join(self.tables.magazine_page),
                    "c": self.tables.page.join(self.tables.magazine_page).join(
                        self.tables.classified_page
                    ),
                },
                None,
                "page_join",
            )
            magazine_page_mapper = mapper(
                MagazinePage,
                self.tables.magazine_page,
                with_polymorphic=("*", magazine_join),
                inherits=page_mapper,
                polymorphic_identity="m",
                properties={
                    "magazine": relationship(
                        Magazine,
                        backref=backref(
                            "pages", order_by=magazine_join.c.page_no
                        ),
                    )
                },
            )
        elif use_joins:
            magazine_join = self.tables.page.join(
                self.tables.magazine_page
            ).outerjoin(self.tables.classified_page)
            magazine_page_mapper = mapper(
                MagazinePage,
                self.tables.magazine_page,
                with_polymorphic=("*", magazine_join),
                inherits=page_mapper,
                polymorphic_identity="m",
                properties={
                    "magazine": relationship(
                        Magazine,
                        backref=backref(
                            "pages", order_by=self.tables.page.c.page_no
                        ),
                    )
                },
            )
        else:
            magazine_page_mapper = mapper(
                MagazinePage,
                self.tables.magazine_page,
                inherits=page_mapper,
                polymorphic_identity="m",
                properties={
                    "magazine": relationship(
                        Magazine,
                        backref=backref(
                            "pages", order_by=self.tables.page.c.page_no
                        ),
                    )
                },
            )

        classified_page_mapper = mapper(
            ClassifiedPage,
            self.tables.classified_page,
            inherits=magazine_page_mapper,
            polymorphic_identity="c",
            primary_key=[self.tables.page.c.id],
        )

        session = create_session()

        pub = Publication(name="Test")
        issue = Issue(issue=46, publication=pub)
        location = Location(ref="ABC", name="London", issue=issue)

        page_size = PageSize(name="A4", width=210, height=297)

        magazine = Magazine(location=location, size=page_size)

        page = ClassifiedPage(magazine=magazine, page_no=1)
        page2 = MagazinePage(magazine=magazine, page_no=2)
        page3 = ClassifiedPage(magazine=magazine, page_no=3)
        session.add(pub)

        session.flush()
        print([x for x in session])
        session.expunge_all()

        session.flush()
        session.expunge_all()
        p = session.query(Publication).filter(Publication.name == "Test").one()

        print(p.issues[0].locations[0].magazine.pages)
        print([page, page2, page3])
        assert repr(p.issues[0].locations[0].magazine.pages) == repr(
            [page, page2, page3]
        ), repr(p.issues[0].locations[0].magazine.pages)
Example #30
0
    def test_multi_level_no_base(self):
        pjoin = polymorphic_union(
            {
                "manager": managers_table,
                "engineer": engineers_table,
                "hacker": hackers_table,
            },
            "type",
            "pjoin",
        )
        pjoin2 = polymorphic_union(
            {"engineer": engineers_table, "hacker": hackers_table},
            "type",
            "pjoin2",
        )
        employee_mapper = mapper(Employee, pjoin, polymorphic_on=pjoin.c.type)
        manager_mapper = mapper(
            Manager,
            managers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="manager",
        )
        engineer_mapper = mapper(
            Engineer,
            engineers_table,
            with_polymorphic=("*", pjoin2),
            polymorphic_on=pjoin2.c.type,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="engineer",
        )
        hacker_mapper = mapper(
            Hacker,
            hackers_table,
            inherits=engineer_mapper,
            concrete=True,
            polymorphic_identity="hacker",
        )
        session = create_session()
        tom = Manager("Tom", "knows how to manage things")

        assert_raises_message(
            AttributeError,
            "does not implement attribute .?'type' at the instance level.",
            setattr,
            tom,
            "type",
            "sometype",
        )

        jerry = Engineer("Jerry", "knows how to program")
        hacker = Hacker("Kurt", "Badass", "knows how to hack")

        assert_raises_message(
            AttributeError,
            "does not implement attribute .?'type' at the instance level.",
            setattr,
            hacker,
            "type",
            "sometype",
        )

        session.add_all((tom, jerry, hacker))
        session.flush()

        # ensure "readonly" on save logic didn't pollute the
        # expired_attributes collection

        assert (
            "nickname"
            not in attributes.instance_state(jerry).expired_attributes
        )
        assert (
            "name" not in attributes.instance_state(jerry).expired_attributes
        )
        assert (
            "name" not in attributes.instance_state(hacker).expired_attributes
        )
        assert (
            "nickname"
            not in attributes.instance_state(hacker).expired_attributes
        )

        def go():
            eq_(jerry.name, "Jerry")
            eq_(hacker.nickname, "Badass")

        self.assert_sql_count(testing.db, go, 0)
        session.expunge_all()
        assert (
            repr(session.query(Employee).filter(Employee.name == "Tom").one())
            == "Manager Tom knows how to manage things"
        )
        assert (
            repr(session.query(Manager).filter(Manager.name == "Tom").one())
            == "Manager Tom knows how to manage things"
        )
        assert set([repr(x) for x in session.query(Employee).all()]) == set(
            [
                "Engineer Jerry knows how to program",
                "Manager Tom knows how to manage things",
                "Hacker Kurt 'Badass' knows how to hack",
            ]
        )
        assert set([repr(x) for x in session.query(Manager).all()]) == set(
            ["Manager Tom knows how to manage things"]
        )
        assert set([repr(x) for x in session.query(Engineer).all()]) == set(
            [
                "Engineer Jerry knows how to program",
                "Hacker Kurt 'Badass' knows how to hack",
            ]
        )
        assert set([repr(x) for x in session.query(Hacker).all()]) == set(
            ["Hacker Kurt 'Badass' knows how to hack"]
        )
Example #31
0
        def test_roundtrip(self):
            parent_table = {"a": ta, "b": tb, "c": tc}[parent]
            child_table = {"a": ta, "b": tb, "c": tc}[child]

            remote_side = None

            if direction == MANYTOONE:
                foreign_keys = [parent_table.c.child_id]
            elif direction == ONETOMANY:
                foreign_keys = [child_table.c.parent_id]

            atob = ta.c.id == tb.c.id
            btoc = tc.c.id == tb.c.id

            if direction == ONETOMANY:
                relationshipjoin = parent_table.c.id == child_table.c.parent_id
            elif direction == MANYTOONE:
                relationshipjoin = parent_table.c.child_id == child_table.c.id
                if parent is child:
                    remote_side = [child_table.c.id]

            abcjoin = polymorphic_union(
                {
                    "a": ta.select(
                        tb.c.id == None,  # noqa
                        from_obj=[ta.outerjoin(tb, onclause=atob)],
                    ),
                    "b": ta.join(tb, onclause=atob)
                    .outerjoin(tc, onclause=btoc)
                    .select(tc.c.id == None)
                    .reduce_columns(),  # noqa
                    "c": tc.join(tb, onclause=btoc).join(ta, onclause=atob),
                },
                "type",
                "abcjoin",
            )

            bcjoin = polymorphic_union(
                {
                    "b": ta.join(tb, onclause=atob)
                    .outerjoin(tc, onclause=btoc)
                    .select(tc.c.id == None)
                    .reduce_columns(),  # noqa
                    "c": tc.join(tb, onclause=btoc).join(ta, onclause=atob),
                },
                "type",
                "bcjoin",
            )

            class A(object):
                def __init__(self, name):
                    self.a_data = name

            class B(A):
                pass

            class C(B):
                pass

            mapper(
                A,
                ta,
                polymorphic_on=abcjoin.c.type,
                with_polymorphic=("*", abcjoin),
                polymorphic_identity="a",
            )
            mapper(
                B,
                tb,
                polymorphic_on=bcjoin.c.type,
                with_polymorphic=("*", bcjoin),
                polymorphic_identity="b",
                inherits=A,
                inherit_condition=atob,
            )
            mapper(
                C,
                tc,
                polymorphic_identity="c",
                inherits=B,
                inherit_condition=btoc,
            )

            parent_mapper = class_mapper({ta: A, tb: B, tc: C}[parent_table])
            child_mapper = class_mapper({ta: A, tb: B, tc: C}[child_table])

            parent_class = parent_mapper.class_
            child_class = child_mapper.class_

            parent_mapper.add_property(
                "collection",
                relationship(
                    child_mapper,
                    primaryjoin=relationshipjoin,
                    foreign_keys=foreign_keys,
                    order_by=child_mapper.c.id,
                    remote_side=remote_side,
                    uselist=True,
                ),
            )

            sess = create_session()

            parent_obj = parent_class("parent1")
            child_obj = child_class("child1")
            somea = A("somea")
            someb = B("someb")
            somec = C("somec")

            # print "APPENDING", parent.__class__.__name__ , "TO",
            # child.__class__.__name__

            sess.add(parent_obj)
            parent_obj.collection.append(child_obj)
            if direction == ONETOMANY:
                child2 = child_class("child2")
                parent_obj.collection.append(child2)
                sess.add(child2)
            elif direction == MANYTOONE:
                parent2 = parent_class("parent2")
                parent2.collection.append(child_obj)
                sess.add(parent2)
            sess.add(somea)
            sess.add(someb)
            sess.add(somec)
            sess.flush()
            sess.expunge_all()

            # assert result via direct get() of parent object
            result = sess.query(parent_class).get(parent_obj.id)
            assert result.id == parent_obj.id
            assert result.collection[0].id == child_obj.id
            if direction == ONETOMANY:
                assert result.collection[1].id == child2.id
            elif direction == MANYTOONE:
                result2 = sess.query(parent_class).get(parent2.id)
                assert result2.id == parent2.id
                assert result2.collection[0].id == child_obj.id

            sess.expunge_all()

            # assert result via polymorphic load of parent object
            result = sess.query(A).filter_by(id=parent_obj.id).one()
            assert result.id == parent_obj.id
            assert result.collection[0].id == child_obj.id
            if direction == ONETOMANY:
                assert result.collection[1].id == child2.id
            elif direction == MANYTOONE:
                result2 = sess.query(A).filter_by(id=parent2.id).one()
                assert result2.id == parent2.id
                assert result2.collection[0].id == child_obj.id
Example #32
0
    def test_multi_level_with_base(self):
        pjoin = polymorphic_union(
            {
                "employee": employees_table,
                "manager": managers_table,
                "engineer": engineers_table,
                "hacker": hackers_table,
            },
            "type",
            "pjoin",
        )
        pjoin2 = polymorphic_union(
            {"engineer": engineers_table, "hacker": hackers_table},
            "type",
            "pjoin2",
        )
        employee_mapper = mapper(
            Employee,
            employees_table,
            with_polymorphic=("*", pjoin),
            polymorphic_on=pjoin.c.type,
        )
        manager_mapper = mapper(
            Manager,
            managers_table,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="manager",
        )
        engineer_mapper = mapper(
            Engineer,
            engineers_table,
            with_polymorphic=("*", pjoin2),
            polymorphic_on=pjoin2.c.type,
            inherits=employee_mapper,
            concrete=True,
            polymorphic_identity="engineer",
        )
        hacker_mapper = mapper(
            Hacker,
            hackers_table,
            inherits=engineer_mapper,
            concrete=True,
            polymorphic_identity="hacker",
        )
        session = create_session()
        tom = Manager("Tom", "knows how to manage things")
        jerry = Engineer("Jerry", "knows how to program")
        hacker = Hacker("Kurt", "Badass", "knows how to hack")
        session.add_all((tom, jerry, hacker))
        session.flush()

        def go():
            eq_(jerry.name, "Jerry")
            eq_(hacker.nickname, "Badass")

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

        # check that we aren't getting a cartesian product in the raw
        # SQL. this requires that Engineer's polymorphic discriminator
        # is not rendered in the statement which is only against
        # Employee's "pjoin"

        assert (
            len(
                testing.db.execute(
                    session.query(Employee).with_labels().statement
                ).fetchall()
            )
            == 3
        )
        assert set([repr(x) for x in session.query(Employee)]) == set(
            [
                "Engineer Jerry knows how to program",
                "Manager Tom knows how to manage things",
                "Hacker Kurt 'Badass' knows how to hack",
            ]
        )
        assert set([repr(x) for x in session.query(Manager)]) == set(
            ["Manager Tom knows how to manage things"]
        )
        assert set([repr(x) for x in session.query(Engineer)]) == set(
            [
                "Engineer Jerry knows how to program",
                "Hacker Kurt 'Badass' knows how to hack",
            ]
        )
        assert set([repr(x) for x in session.query(Hacker)]) == set(
            ["Hacker Kurt 'Badass' knows how to hack"]
        )
Example #33
0
    def test_insert_order(self):
        """test that classes of multiple types mix up mapper inserts
        so that insert order of individual tables is maintained"""

        person_join = polymorphic_union(
            {
                "engineer": people.join(engineers),
                "manager": people.join(managers),
                "person": people.select(people.c.type == "person"),
            },
            None,
            "pjoin",
        )

        person_mapper = mapper(
            Person,
            people,
            with_polymorphic=("*", person_join),
            polymorphic_on=person_join.c.type,
            polymorphic_identity="person",
        )

        mapper(
            Engineer,
            engineers,
            inherits=person_mapper,
            polymorphic_identity="engineer",
        )
        mapper(
            Manager,
            managers,
            inherits=person_mapper,
            polymorphic_identity="manager",
        )
        mapper(
            Company,
            companies,
            properties={
                "employees": relationship(
                    Person, backref="company", order_by=person_join.c.person_id
                )
            },
        )

        session = create_session()
        c = Company(name="company1")
        c.employees.append(
            Manager(
                status="AAB",
                manager_name="manager1",
                name="pointy haired boss",
            )
        )
        c.employees.append(
            Engineer(
                status="BBA",
                engineer_name="engineer1",
                primary_language="java",
                name="dilbert",
            )
        )
        c.employees.append(Person(status="HHH", name="joesmith"))
        c.employees.append(
            Engineer(
                status="CGG",
                engineer_name="engineer2",
                primary_language="python",
                name="wally",
            )
        )
        c.employees.append(
            Manager(status="ABA", manager_name="manager2", name="jsmith")
        )
        session.add(c)
        session.flush()
        session.expunge_all()
        eq_(session.query(Company).get(c.company_id), c)
Example #34
0
    def test_roundtrip(self):
        if with_polymorphic == "unions":
            if include_base:
                person_join = polymorphic_union(
                    {
                        "engineer": people.join(engineers),
                        "manager": people.join(managers),
                        "person": people.select(people.c.type == "person"),
                    },
                    None,
                    "pjoin",
                )
            else:
                person_join = polymorphic_union(
                    {
                        "engineer": people.join(engineers),
                        "manager": people.join(managers),
                    },
                    None,
                    "pjoin",
                )

            manager_join = people.join(managers).outerjoin(boss)
            person_with_polymorphic = ["*", person_join]
            manager_with_polymorphic = ["*", manager_join]
        elif with_polymorphic == "joins":
            person_join = (
                people.outerjoin(engineers).outerjoin(managers).outerjoin(boss)
            )
            manager_join = people.join(managers).outerjoin(boss)
            person_with_polymorphic = ["*", person_join]
            manager_with_polymorphic = ["*", manager_join]
        elif with_polymorphic == "auto":
            person_with_polymorphic = "*"
            manager_with_polymorphic = "*"
        else:
            person_with_polymorphic = None
            manager_with_polymorphic = None

        if redefine_colprop:
            person_mapper = mapper(
                Person,
                people,
                with_polymorphic=person_with_polymorphic,
                polymorphic_on=people.c.type,
                polymorphic_identity="person",
                properties={"person_name": people.c.name},
            )
        else:
            person_mapper = mapper(
                Person,
                people,
                with_polymorphic=person_with_polymorphic,
                polymorphic_on=people.c.type,
                polymorphic_identity="person",
            )

        mapper(
            Engineer,
            engineers,
            inherits=person_mapper,
            polymorphic_identity="engineer",
        )
        mapper(
            Manager,
            managers,
            inherits=person_mapper,
            with_polymorphic=manager_with_polymorphic,
            polymorphic_identity="manager",
        )

        mapper(Boss, boss, inherits=Manager, polymorphic_identity="boss")

        mapper(
            Company,
            companies,
            properties={
                "employees": relationship(
                    Person,
                    lazy=lazy_relationship,
                    cascade="all, delete-orphan",
                    backref="company",
                    order_by=people.c.person_id,
                )
            },
        )

        if redefine_colprop:
            person_attribute_name = "person_name"
        else:
            person_attribute_name = "name"

        employees = [
            Manager(
                status="AAB",
                manager_name="manager1",
                **{person_attribute_name: "pointy haired boss"}
            ),
            Engineer(
                status="BBA",
                engineer_name="engineer1",
                primary_language="java",
                **{person_attribute_name: "dilbert"}
            ),
        ]
        if include_base:
            employees.append(Person(**{person_attribute_name: "joesmith"}))
        employees += [
            Engineer(
                status="CGG",
                engineer_name="engineer2",
                primary_language="python",
                **{person_attribute_name: "wally"}
            ),
            Manager(
                status="ABA",
                manager_name="manager2",
                **{person_attribute_name: "jsmith"}
            ),
        ]

        pointy = employees[0]
        jsmith = employees[-1]
        dilbert = employees[1]

        session = create_session()
        c = Company(name="company1")
        c.employees = employees
        session.add(c)

        session.flush()
        session.expunge_all()

        eq_(session.query(Person).get(dilbert.person_id), dilbert)
        session.expunge_all()

        eq_(
            session.query(Person)
            .filter(Person.person_id == dilbert.person_id)
            .one(),
            dilbert,
        )
        session.expunge_all()

        def go():
            cc = session.query(Company).get(c.company_id)
            eq_(cc.employees, employees)

        if not lazy_relationship:
            if with_polymorphic != "none":
                self.assert_sql_count(testing.db, go, 1)
            else:
                self.assert_sql_count(testing.db, go, 5)

        else:
            if with_polymorphic != "none":
                self.assert_sql_count(testing.db, go, 2)
            else:
                self.assert_sql_count(testing.db, go, 6)

        # test selecting from the query, using the base
        # mapped table (people) as the selection criterion.
        # in the case of the polymorphic Person query,
        # the "people" selectable should be adapted to be "person_join"
        eq_(
            session.query(Person)
            .filter(getattr(Person, person_attribute_name) == "dilbert")
            .first(),
            dilbert,
        )

        assert (
            session.query(Person)
            .filter(getattr(Person, person_attribute_name) == "dilbert")
            .first()
            .person_id
        )

        eq_(
            session.query(Engineer)
            .filter(getattr(Person, person_attribute_name) == "dilbert")
            .first(),
            dilbert,
        )

        # test selecting from the query, joining against
        # an alias of the base "people" table.  test that
        # the "palias" alias does *not* get sucked up
        # into the "person_join" conversion.
        palias = people.alias("palias")
        dilbert = session.query(Person).get(dilbert.person_id)
        is_(
            dilbert,
            session.query(Person)
            .filter(
                (palias.c.name == "dilbert")
                & (palias.c.person_id == Person.person_id)
            )
            .first(),
        )
        is_(
            dilbert,
            session.query(Engineer)
            .filter(
                (palias.c.name == "dilbert")
                & (palias.c.person_id == Person.person_id)
            )
            .first(),
        )
        is_(
            dilbert,
            session.query(Person)
            .filter(
                (Engineer.engineer_name == "engineer1")
                & (engineers.c.person_id == people.c.person_id)
            )
            .first(),
        )
        is_(
            dilbert,
            session.query(Engineer).filter(
                Engineer.engineer_name == "engineer1"
            )[0],
        )

        session.flush()
        session.expunge_all()

        def go():
            session.query(Person).filter(
                getattr(Person, person_attribute_name) == "dilbert"
            ).first()

        self.assert_sql_count(testing.db, go, 1)
        session.expunge_all()
        dilbert = (
            session.query(Person)
            .filter(getattr(Person, person_attribute_name) == "dilbert")
            .first()
        )

        def go():
            # assert that only primary table is queried for
            # already-present-in-session
            d = (
                session.query(Person)
                .filter(getattr(Person, person_attribute_name) == "dilbert")
                .first()
            )

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

        # test standalone orphans
        daboss = Boss(
            status="BBB",
            manager_name="boss",
            golf_swing="fore",
            **{person_attribute_name: "daboss"}
        )
        session.add(daboss)
        assert_raises(sa_exc.DBAPIError, session.flush)

        c = session.query(Company).first()
        daboss.company = c
        manager_list = [e for e in c.employees if isinstance(e, Manager)]
        session.flush()
        session.expunge_all()

        eq_(
            session.query(Manager).order_by(Manager.person_id).all(),
            manager_list,
        )
        c = session.query(Company).first()

        session.delete(c)
        session.flush()

        eq_(select([func.count("*")]).select_from(people).scalar(), 0)
Example #35
0
                    self.name + " " +  self.manager_data


class Engineer(Employee):
    def __init__(self, name, engineer_info):
        self.name = name
        self.engineer_info = engineer_info

    def __repr__(self):
        return self.__class__.__name__ + " " + \
                    self.name + " " +  self.engineer_info


pjoin = polymorphic_union(
    {
        'manager': managers_table,
        'engineer': engineers_table
    }, 'type', 'pjoin')

employee_mapper = mapper(Employee, pjoin, polymorphic_on=pjoin.c.type)
manager_mapper = mapper(Manager,
                        managers_table,
                        inherits=employee_mapper,
                        concrete=True,
                        polymorphic_identity='manager')
engineer_mapper = mapper(Engineer,
                         engineers_table,
                         inherits=employee_mapper,
                         concrete=True,
                         polymorphic_identity='engineer')
Example #36
0
    def test_merge_w_relationship(self):
        A, C, B, c_table, b_table, a_table, Dest, dest_table = (
            self.classes.A,
            self.classes.C,
            self.classes.B,
            self.tables.c_table,
            self.tables.b_table,
            self.tables.a_table,
            self.classes.Dest,
            self.tables.dest_table,
        )

        ajoin = polymorphic_union(
            {"a": a_table, "b": b_table, "c": c_table}, "type", "ajoin"
        )
        mapper(
            A,
            a_table,
            with_polymorphic=("*", ajoin),
            polymorphic_on=ajoin.c.type,
            polymorphic_identity="a",
            properties={
                "some_dest": relationship(Dest, back_populates="many_a")
            },
        )
        mapper(
            B,
            b_table,
            inherits=A,
            concrete=True,
            polymorphic_identity="b",
            properties={
                "some_dest": relationship(Dest, back_populates="many_a")
            },
        )

        mapper(
            C,
            c_table,
            inherits=A,
            concrete=True,
            polymorphic_identity="c",
            properties={
                "some_dest": relationship(Dest, back_populates="many_a")
            },
        )

        mapper(
            Dest,
            dest_table,
            properties={
                "many_a": relationship(
                    A, back_populates="some_dest", order_by=ajoin.c.id
                )
            },
        )

        assert C.some_dest.property.parent is class_mapper(C)
        assert B.some_dest.property.parent is class_mapper(B)
        assert A.some_dest.property.parent is class_mapper(A)

        sess = sessionmaker()()
        dest1 = Dest(name="d1")
        dest2 = Dest(name="d2")
        a1 = A(some_dest=dest2, aname="a1")
        b1 = B(some_dest=dest1, bname="b1")
        c1 = C(some_dest=dest2, cname="c1")
        sess.add_all([dest1, dest2, c1, a1, b1])
        sess.commit()

        sess2 = sessionmaker()()
        merged_c1 = sess2.merge(c1)
        eq_(merged_c1.some_dest.name, "d2")
        eq_(merged_c1.some_dest_id, c1.some_dest_id)
Example #37
0
    def setup_mapper(self):
        '''
        Initializes and assign a mapper to the entity.
        At this point the mapper will usually have no property as they are
        added later.
        '''
        if self.entity.mapper:
            return

        # for now we don't support the "abstract" parent class in a concrete
        # inheritance scenario as demonstrated in
        # sqlalchemy/test/orm/inheritance/concrete.py
        # this should be added along other
        kwargs = self.mapper_options
        if self.order_by:
            kwargs['order_by'] = self.translate_order_by(self.order_by)

        if self.version_id_col:
            kwargs['version_id_col'] = self.get_column(self.version_id_col)

        if self.inheritance in ('single', 'concrete', 'multi'):
            if self.parent and \
               not (self.inheritance == 'concrete' and not self.polymorphic):
                kwargs['inherits'] = self.parent.mapper

            if self.inheritance == 'multi' and self.parent:
                col_pairs = zip(self.primary_keys,
                                self.parent._descriptor.primary_keys)
                kwargs['inherit_condition'] = \
                    and_(*[pc == c for c, pc in col_pairs])

            if self.polymorphic:
                if self.children:
                    if self.inheritance == 'concrete':
                        keys = [(self.identity, self.entity.table)]
                        keys.extend([(child._descriptor.identity, child.table)
                                     for child in self._get_children()])
                        #XXX: we might need to change the alias name so that
                        # children (which are parent themselves) don't end up
                        # with the same alias than their parent?
                        pjoin = polymorphic_union(
                                    dict(keys), self.polymorphic, 'pjoin')

                        kwargs['with_polymorphic'] = ('*', pjoin)
                        kwargs['polymorphic_on'] = \
                            getattr(pjoin.c, self.polymorphic)
                    elif not self.parent:
                        kwargs['polymorphic_on'] = \
                            self.get_column(self.polymorphic)

                    #TODO: this is an optimization, and it breaks the multi
                    # table polymorphic inheritance test with a relation.
                    # So I turn it off for now. We might want to provide an
                    # option to turn it on.
#                    if self.inheritance == 'multi':
#                        children = self._get_children()
#                        join = self.entity.table
#                        for child in children:
#                            join = join.outerjoin(child.table)
#                        kwargs['select_table'] = join

                if self.children or self.parent:
                    kwargs['polymorphic_identity'] = self.identity

                if self.parent and self.inheritance == 'concrete':
                    kwargs['concrete'] = True

        #TODO: document this!
        if 'primary_key' in kwargs:
            cols = self.entity.table.c
            kwargs['primary_key'] = [getattr(cols, colname) for
                colname in kwargs['primary_key']]

        if self.parent and self.inheritance == 'single':
            args = []
        else:
            args = [self.entity.table]

        # do the mapping
        if self.session is None:
            self.entity.mapper = mapper(self.entity, *args, **kwargs)
        elif isinstance(self.session, ScopedSession):
            self.entity.mapper = self.session.mapper(self.entity,
                                                     *args, **kwargs)
        else:
            raise Exception("Failed to map entity '%s' with its table or "
                            "selectable" % self.entity.__name__)