
from sa_gentestbase import *
MBase=Base
class AB( Test_AB0):
    def test_ABC_poly_1__inh_t__Alazy_B__inhB_A__Blazy___BAlazy___inhC_B__Clazy___CAlazy___CBlazy_( me):
        meta=me.meta
        table_A = Table( 'A', meta,
            Column( 'linkA_id', Integer, ForeignKey( 'B.db_id',     name= 'linkA_id_fk',     use_alter= True, ), ),
            Column( 'name',   type= String, ),
            Column( 'db_id',   primary_key= True,   type= Integer, ),
            Column( 'atype',   type= String, ),
        )
        table_B = Table( 'B', meta,
            Column( 'dataB',   type= String, ),
            Column( 'db_id', Integer, ForeignKey( 'A.db_id', ),   primary_key= True, ),
        )
        table_C = Table( 'C', meta,
            Column( 'dataC',   type= String, ),
            Column( 'db_id', Integer, ForeignKey( 'B.db_id', ),   primary_key= True, ),
        )
        table_D = Table( 'D', meta,
            Column( 'dataD',   type= String, ),
            Column( 'db_id', Integer, ForeignKey( 'C.db_id', ),   primary_key= True, ),
        )

        meta.create_all()

        class A( MBase):
            props = ['db_id', 'linkA', 'name']
        class B( A):
            props = ['db_id', 'linkA', 'name', 'dataB']
        class C( B):
            props = ['db_id', 'linkA', 'name', 'dataC', 'dataB']
        class D( C):
            props = ['db_id', 'dataD', 'linkA', 'name', 'dataC', 'dataB']

        pu_a = polymorphic_union( {
                        'A': table_A.select( table_A.c.atype == 'A', ).alias( 'bz4A' ),
                        'C': select( [table_A, table_B.c.dataB, table_C.c.dataC], table_A.c.atype == 'C', from_obj= [join( join( table_A, table_B, table_B.c.db_id == table_A.c.db_id, ), table_C, table_C.c.db_id == table_B.c.db_id, )], ).alias( 'bz4C' ),
                        'B': select( [table_A, table_B.c.dataB], table_A.c.atype == 'B', from_obj= [join( table_A, table_B, table_B.c.db_id == table_A.c.db_id, )], ).alias( 'bz4B' ),
                        'D': join( join( join( table_A, table_B, table_B.c.db_id == table_A.c.db_id, ), table_C, table_C.c.db_id == table_B.c.db_id, ), table_D, table_D.c.db_id == table_C.c.db_id, ),
                        }, None, 'pu_a', ) #tableinh
        mapper_A = mapper( A, table_A,
                    polymorphic_identity= 'A',
                    polymorphic_on= pu_a.c.atype,
                    select_table= pu_a,
                    )
        mapper_A.add_property( 'linkA', relation( B,
                    foreign_keys= table_A.c.linkA_id,
                    lazy= True,
                    post_update= True,
                    primaryjoin= table_A.c.linkA_id == table_B.c.db_id,
                    remote_side= table_B.c.db_id,
                    uselist= False,
                    ) )

        pu_b = polymorphic_union( {
                        'C': select( [table_A, table_B.c.dataB, table_C.c.dataC], table_A.c.atype == 'C', from_obj= [join( join( table_A, table_B, table_B.c.db_id == table_A.c.db_id, ), table_C, table_C.c.db_id == table_B.c.db_id, )], ).alias( 'bz4C' ),
                        'B': select( [table_A, table_B.c.dataB], table_A.c.atype == 'B', from_obj= [join( table_A, table_B, table_B.c.db_id == table_A.c.db_id, )], ).alias( 'bz4B' ),
                        'D': join( join( join( table_A, table_B, table_B.c.db_id == table_A.c.db_id, ), table_C, table_C.c.db_id == table_B.c.db_id, ), table_D, table_D.c.db_id == table_C.c.db_id, ),
                        }, None, 'pu_b', ) #tableinh
        mapper_B = mapper( B, table_B,
                    inherit_condition= table_B.c.db_id == table_A.c.db_id,
                    inherits= mapper_A,
                    polymorphic_identity= 'B',
                    polymorphic_on= pu_b.c.atype,
                    select_table= pu_b,
                    )

        pu_c = polymorphic_union( {
                        'C': select( [table_A, table_B.c.dataB, table_C.c.dataC], table_A.c.atype == 'C', from_obj= [join( join( table_A, table_B, table_B.c.db_id == table_A.c.db_id, ), table_C, table_C.c.db_id == table_B.c.db_id, )], ).alias( 'bz4C' ),
                        'D': join( join( join( table_A, table_B, table_B.c.db_id == table_A.c.db_id, ), table_C, table_C.c.db_id == table_B.c.db_id, ), table_D, table_D.c.db_id == table_C.c.db_id, ),
                        }, None, 'pu_c', ) #tableinh
        mapper_C = mapper( C, table_C,
                    inherit_condition= table_C.c.db_id == table_B.c.db_id,
                    inherits= mapper_B,
                    polymorphic_identity= 'C',
                    polymorphic_on= pu_c.c.atype,
                    select_table= pu_c,
                    )

        mapper_D = mapper( D, table_D,
                    inherit_condition= table_D.c.db_id == table_C.c.db_id,
                    inherits= mapper_C,
                    polymorphic_identity= 'D',
                    )


        mapper_A1 = mapper( A, table_A.select( table_A.c.atype == 'A', ).alias( 'bz4A' ),
                    non_primary= True,
                    polymorphic_identity= 'A',
                    )

        mapper_B1 = mapper( B, select( [table_A, table_B.c.dataB], table_A.c.atype == 'B', from_obj= [join( table_A, table_B, table_B.c.db_id == table_A.c.db_id, )], ).alias( 'bz4B' ),
                    non_primary= True,
                    polymorphic_identity= 'B',
                    )

        mapper_C1 = mapper( C, select( [table_A, table_B.c.dataB, table_C.c.dataC], table_A.c.atype == 'C', from_obj= [join( join( table_A, table_B, table_B.c.db_id == table_A.c.db_id, ), table_C, table_C.c.db_id == table_B.c.db_id, )], ).alias( 'bz4C' ),
                    non_primary= True,
                    polymorphic_identity= 'C',
                    )



        #populate
        a = A()
        b = B()
        c = C()
        a.linkA = b
        a.name = 'anna'
        b.name = 'ben'
        b.dataB = 'gun'
        c.name = 'cc'
        c.dataC = 'mc'

        session = create_session()
        session.save(a)
        session.save(b)
        session.save(c)
        session.flush()

        expects = [
            dict( klas= A, table= table_A, oid= a.db_id, exp_single= str(a),
                    exp_multi = [ str(a), str(b), str(c) ]),
            dict( klas= B, table= table_B, oid= b.db_id, exp_single= str(b),
                    exp_multi = [ str(b), str(c) ]),
            dict( klas= C, table= table_C, oid= c.db_id, exp_single= str(c),
                    exp_multi = [ str(c) ]),

        ]

        me.query( session, expects, idname='db_id' )

        """
AssertionError: Could not find corresponding column for B.db_id in selectable SELECT "bz4C".db_id, "bz4C".name, CAST(NULL AS TEXT) AS "dataD", "bz4C"."linkA_id", "bz4C".atype, "bz4C"."dataC", "bz4C"."dataB"
FROM (SELECT "A"."linkA_id" AS "linkA_id", "A".name AS name, "A".db_id AS db_id, "A".atype AS atype, "B"."dataB" AS "dataB", "C"."dataC" AS "dataC"
FROM "A" JOIN "B" ON "B".db_id = "A".db_id JOIN "C" ON "C".db_id = "B".db_id
WHERE "A".atype = ?) AS "bz4C" UNION ALL SELECT "bz4B".db_id, "bz4B".name, CAST(NULL AS TEXT) AS "dataD", "bz4B"."linkA_id", "bz4B".atype, CAST(NULL AS TEXT) AS "dataC", "bz4B"."dataB"
FROM (SELECT "A"."linkA_id" AS "linkA_id", "A".name AS name, "A".db_id AS db_id, "A".atype AS atype, "B"."dataB" AS "dataB"
FROM "A" JOIN "B" ON "B".db_id = "A".db_id
WHERE "A".atype = ?) AS "bz4B" UNION ALL SELECT "D".db_id, "A".name, "D"."dataD", "A"."linkA_id", "A".atype, "C"."dataC", "B"."dataB"
FROM "A" JOIN "B" ON "B".db_id = "A".db_id JOIN "C" ON "C".db_id = "B".db_id JOIN "D" ON "D".db_id = "C".db_id


"""


if __name__ == '__main__':
    setup()
    unittest.main()
