uniqueconstraint attachment logic fails for combination of Column + string names

Issue #3411 resolved
Mike Bayer repo owner created an issue
from sqlalchemy import *
import random

m = MetaData()

columns = [Column('a', Integer), Column('b', Integer), Column('c', Integer)]
uq = UniqueConstraint(columns[0], 'b', 'c')

random.shuffle(columns)
t = Table('t', m, *(columns + [uq]))

based on the order of columns, the attach event associated with "a" will prematurely cause the constraint to initialize itself before the table is set up.

The original case arises due to a declarative mapping that combines column objects with string names, and the ordering changes due to changes in declared_attr:

class Foo(object):

    foo = Column(Unicode(64), nullable=False)

    @declared_attr
    def bar(cls):
        return Column("bar", Integer)


class ItemCategory(Base, Foo):
    __tablename__ = 'item_category'

    id = Column(Integer, primary_key=True)
    name = Column(Unicode(64), nullable=False)

    __table_args__ = (
        UniqueConstraint(name, "foo", "bar",
                         name='unique_category_and_parent'),)

Comments (4)

  1. Mike Bayer reporter
    • Fixed bug in enhanced constraint-attachment logic introduced in 🎫3341 where in the unusual case of a constraint that refers to a mixture of :class:.Column objects and string column names at the same time, the auto-attach-on-column-attach logic will be skipped; for the constraint to be auto-attached in this case, all columns must be assembled on the target table up front. Added a new section to the migration document regarding the original feature as well as this change. fixes #3411

    → <<cset 77db0ef6ac03>>

  2. Log in to comment