Clone wiki

sqlalchemy / UsageRecipes / IteratePropsInCreationOrder


Note: This recipe uses non-public APIs. Compatibility is subject to change without notice in a future release.

Python classes do not store their attributes in order, nor do they pass along to the metaclass how they were ordered. This means:

class Foo(object):
   a = 1
   b = 2
   c = 3

calling dir(Foo) is not guaranteed in any way to return a, b, c in any kind of order.

SQLAlchemy does apply a "sort key" to MapperProperty and Column objects as they are ''created'', however. You can use these to iterate through attributes ''as they were created'':

class MyClass(Base):
   __tablename__ = 'foo'

   c1 = Column(Integer, primary_key=True)
   r2 = relationship("Bar")
   c3 = Column(String)

from sqlalchemy.orm import class_mapper
from import ColumnProperty
mapper = class_mapper(MyClass)

props = list(mapper.iterate_properties)

def _order_for_prop(prop):
    # the ColumnProperty is created after MyClass
    # is mapped, so their _creation_order is after
    # that of each Column.  So we need to look at the actual
    # Column object.
    if isinstance(prop, ColumnProperty):
        return prop.columns[0]._creation_order
        return prop._creation_order

print [p.key for p in props]