Two different attributes mapped to same-named fields of different tables backing polymorphed class get incorrect value assigned on commit.

Issue #2307 resolved
Former user created an issue

The issue seems to be dependent on names of data fields being identical and referencing same table as FK (as soon as switch either table to have different column name the problem seem to disappear) The project I am involved in has a standard convention for naming foreign key fields (table_column) and since both tables which are backing polymorphed class reference same other table (for different purposes) - the columns defining the relations have same names. The properties of classes these columns are mapped to are different and despite that when either of properties gets assigned both fields get value on session commit.

Comments (2)

  1. Mike Bayer repo owner

    OK I forgot your name on IRC but I was definitely given this exact test case some days ago on IRC, as it even includes the same syntax errors (class Person() and not class Person(object)). I posted the solution to the channel within about 10 minutes, so I'm not really sure what went wrong here. If an IRC conversation is severed, the mailing list is always the best place to bring issues like these. The description here, "two different attributes", is not what the test case states; "person_name" as an attribute is not disambiguated at all versus the column present in the sub table versus the parent table. The solution is to simply disambiguate:

    # docs say inherits property should point to base class
    mapper(ServeBeer, serve_beer_table, inherits=Task,
        polymorphic_identity='beer',
        properties={
            'sub_person_name':serve_beer_table.c.person_name,
            'servant' : relationship(Person),
            'beer': column_property(serve_beer_table.c.beer)
        }
    )
    
    # and example say it should point to it's mapper
    mapper(GiveCheck, give_check_table, inherits=task_mapper,
        polymorphic_identity='check',
        properties={
            'sub_person_name':give_check_table.c.person_name,
            'customer' : relationship(Person),
            'amount': column_property(give_check_table.c.amount)
        }
    )
    

    test passes.

  2. Log in to comment