Упорядочение отношений по свойству дочерних элементов - PullRequest
1 голос
/ 29 сентября 2019

Я использую flask-sqlalchemy в проекте Flask для моделирования своей базы данных.
Мне нужно отсортировать элементы отношения «многие ко многим» на основе свойств различных дочерних элементов одной стороны.

У меня есть "Работа" (родительский элемент), "Метка" (дочерние элементы), "Тип" (отношение один ко многим наTag) и «Block» (отношение типа «один ко многим» в типе). Теги и работы объединяются с таблицей сопоставления "work_tag_mapping" .

По сути, каждый тег имеет ровно один тип, каждый тип принадлежит ровно одному блоку, и многие теги могут быть добавлены вмного работ.

Теперь я хочу, чтобы список тегов в работе сортировался по первому блоку и второму типу (для этого у обоих есть столбец "position").

Вот мои таблицы(упрощенно ради вопроса):

class Work(db.Model):
  __tablename__ = 'work'
  id = db.Column(db.Integer, primary_key=True)
  name = db.Column(db.String(255, collation='utf8_bin'))
  tags = db.relationship('Tag', order_by="Tag.type.block.position, Tag.type.position", secondary=work_tag_mapping)

class Tag(db.Model):
  __tablename__ = 'tag'
  id = db.Column(db.Integer, primary_key=True)
  name = db.Column(db.String(255, collation='utf8_bin'))
  type_id = db.Column(db.Integer, db.ForeignKey('type.id'), nullable=False)
  type = db.relationship('Type')

work_tag_mapping = db.Table('work_tag_mapping',  
    db.Column('id', db.Integer, primary_key=True),
    db.Column('work_id', db.Integer, db.ForeignKey('work.id'), nullable=False),
    db.Column('tag_id', db.Integer, db.ForeignKey('tag.id'), nullable=False)
)

class Type(db.Model):
  __tablename__ = 'type'
  id = db.Column(db.Integer, primary_key=True)
  name = db.Column(db.String(255, collation='utf8_bin'))
  position = db.Column(db.Integer)
  block_id = db.Column(db.Integer, db.ForeignKey('block.id'), nullable=False)
  block = db.relationship('Block')

class Block(db.Model):
  __tablename__ = 'block'
  id = db.Column(db.Integer, primary_key=True)
  name = db.Column(db.String(255, collation='utf8_bin'))
  position = db.Column(db.Integer)

Теперь, это "order_by" в отношении "тегов", которое не работает, как я изначально надеялся. Я получаю сообщение об ошибке: "sqlalchemy.exc.InvalidRequestError: Property 'type' is not an instance of ColumnProperty (i.e. does not correspond directly to a Column)."

Я новичок в SQLalchemy, Flask и, действительно, в Python, и ни один из ресурсов или вопросов здесь не упоминает такой случай.

1 Ответ

2 голосов
/ 30 сентября 2019

Хотя это кажется невозможным напрямую, добавление геттера и выполнение сортировки при получении делает свое дело. Добавление lazy='dynamic' гарантирует, что коллекция ведет себя как запрос, поэтому можно выполнять объединения.

_tags = db.relationship('Tag', lazy='dynamic')

    @hybrid_property
    def tags(self):
        return self._tags.join(Type).join(Block).order_by(Block.position, Type.position)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...