2014-11-30 2 views
2

Предположим, что у меня есть такая таблицаSQLAlchemy декларативный наследование __table_args__

class Base(object): 
    id = Column(Integer, primary_key=True) 
    date_updated = Column(Date, nullable=True) 
    rating = Column(Integer, nullable=False, default=0) 
    status = Column(SmallInteger, nullable=False, default=0) 

    @declared_attr 
    def __tablename__(cls): 
     return "table_%s" % cls.LANG 

    @declared_attr 
    def __table_args__(cls): 
     return (
      Index('ix__%s__rating' % cls.__tablename__, 'rating'), 
      Index(
       'ix__%s__status' % cls.__tablename__, 
       'status', 
       postgresql_where=column('status') == 0, 
      ), 
      Index(
       'ix__%s__date_updated' % cls.__tablename__, 
       'date_updated', 
       postgresql_where=column('date_updated') != None, 
      ), 
     ) 

    class TableEn(Base, db.Model): 
     LANG = 'en' 


    class TableUk(Base, db.Model): 
     LANG = 'uk' 

каким-то образом я нашел, как создавать такие (частичные) индексы, как status и date_updated в родительских __table_args__.

Но мне нужно создать убывание сортировки индекса rating, как func.desc(rating), но я не знаю, как сделать это.

Ни один из вариантов не работает для меня (вариант, и это ошибка):

  • Index('ix__%s__rating' % cls.__tablename__, 'rating desc')

    исключение KeyError: 'Рейтинг DESC'

  • Index('ix__%s__rating' % cls.__tablename__, cls.rating.desc())

    SQLAlchemy. exc.ArgumentError: нельзя добавлять неназванные co lumn в коллекции колонке

  • Index('ix__%s__rating' % cls.__tablename__, desc('rating'))

    при создании схемы в БД

    sqlalchemy.exc.ProgrammingError: (ProgrammingError) ошибка синтаксиса или вблизи ")" ЛИНИЯ 1: CREATE INDEX ON ix__table_en__rating table_en()

конечно, я могу создать этот индекс вручную с помощью прямого SQL, но я уверенное решение существует где-то.

Заранее благодарен!

ответ

1

Вот упрощенный код, который делает то, что вы хотите:

class BaseModel(Base): 

    __abstract__ = True 

    id = Column(Integer, primary_key=True) 
    rating = Column(Integer, nullable=False, default=0) 

    @declared_attr 
    def __tablename__(cls): 
     return "table_%s" % cls.LANG 

    @classmethod 
    def build_indexes(cls): 
     Index('ix__%s__rating' % cls.__tablename__, cls.__table__.c.rating.desc()) 


@event.listens_for(BaseModel, 'instrument_class', propagate=True) 
def receive_mapper_configured(mapper, class_): 
    class_.build_indexes() 


class TableEn(BaseModel): 
    LANG = 'en' 


class TableUk(BaseModel): 
    LANG = 'uk' 

Полный код here.

Здесь у вас есть 2 проблемы. Во-первых, вы должны позвонить desc в столбец таблицы, а не атрибут объекта mapper. Но если вы это сделаете, у вас есть проблема, потому что атрибут __table__ создается после получения информации от __table__args__. Поэтому вам необходимо создать индексы после создания поля __table__. Один из способов сделать это - через события sqlalchemy.

Смежные вопросы