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, ),
        )

        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']

        pu_a = polymorphic_union( {
                        'A': table_A.select( table_A.c.atype == 'A', ).alias( 'bz4A' ),
                        'C': 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, ),
                        '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' ),
                        }, 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': 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, ),
                        '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' ),
                        }, 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,
                    )

        mapper_C = mapper( C, table_C,
                    inherit_condition= table_C.c.db_id == table_B.c.db_id,
                    inherits= mapper_B,
                    polymorphic_identity= 'C',
                    )


        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',
                    )



        #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' )

        """
A.query_BASE_instances: AssertionError:
 result=['A( linkA=None name=anna )']
 expect=['A( linkA=>B/id2/ben name=anna )']
A.query_ALL_instances: AssertionError:
 result=['A( linkA=None name=anna )', 'B( linkA=None name=ben dataB=gun )', 'C( linkA=None name=cc dataC=mc dataB=None )']
 expect=['A( linkA=>B/id2/ben name=anna )', 'B( linkA=None name=ben dataB=gun )', 'C( linkA=None name=cc dataC=mc dataB=None )']


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

