Declarative system does not keep the mapper order as defined in the class when using relationship.

Issue #2444 resolved
Cosmia created an issue

Declarative system keeps order in mapper same as the order in class definition, like

class Model(Base):
    __tablename__='model'
    f1 = Column(Integer, primary_key=True)
    f2 = Column(Integer)
    f3 = Column(Integer)
    f4 = Column(Integer)
    f5 = Column(Integer)

for prop in Model.__mapper__.iterate_properties:
    print prop.key

And code above will print:

f1
f2
f3
f4
f5

But relationship property adds them to the top of the list:

class Parent(Base):
    __tablename__='parent'
    f1 = Column(Integer, primary_key=True)
    f2 = Column(Integer)
    f3 = Column(Integer)

class Model(Base):
    __tablename__='model'
    f1 = Column(Integer, primary_key=True)
    f2 = Column(Integer)
    f3 = Column(Integer, ForeignKey('parent.f1'))
    f3_5 = relationship(Parent)
    f4 = Column(Integer)
    f5 = Column(Integer)


for prop in Model.__mapper__.iterate_properties:
    print prop.key

prints

f3_5
f1
f2
f3
f4
f5

The order makes sense when the model is made from factory, in that case, I don't know the fields of the model until running. For example WTAlchemy use this it to generate the form for the model.

Comments (2)

  1. Mike Bayer repo owner

    Replying to Cosmius:

    Declarative system keeps order in mapper same as the order in class definition, like

    not really. The Column object itself keeps a counter so that the ordering of sometable.c is ordered, for the purposes of generating DDL. Anything else declared in the class has no sort key applied to it.

    Ordering of mapper properties is not part of the SQLAlchemy behavioral contract, only the collection of Column objects on sometable.c. The _props dictionary is an ordered dict but this is primarily for the benefit of SQLAlchemy's unit tests to ensure that SQL statements, which we assert against fixed strings, are generated in a deterministic way.

    Similarly, Python classes are not ordered in terms of their attributes. So when you say:

    class SomeClass(object):
        a = 5
        b = 4
        c = 6
    

    there is no ordering whatsoever to a, b, and c. If WTAlchemy is expecting dir(SomeClass) to deterministically produce a, b, c, it's broken.

  2. Log in to comment