#python #sqlalchemy
Вопрос:
У меня есть таблица со следующей структурой:
id = db.Column(db.BigInteger, primary_key=True) child1Id = db.Column(db.BigInteger, db.ForeignKey('child1.id')) child1 = db.relationship("Child1Model", uselist=False, foreign_keys=[child1Id]) child2Id = db.Column(db.BigInteger, db.ForeignKey('child2.id')) child2 = db.relationship("Child2Model", uselist=False, foreign_keys=[child2Id]) child3Id = db.Column(db.BigInteger, db.ForeignKey('child3.id')) child3 = db.relationship("Child3Model", uselist=False, foreign_keys=[child3Id])
Все 3 дочерние таблицы имеют идентификатор и имя, среди других столбцов. Для сортировки родителя по имени child1 я определил следующее гибридное свойство и выражение:
@hybrid_property def child1Name(self): return self.child1.name @child1Name.expression def child1Name(cls): return select([Child1Model.name]).where(Child1Model.id == cls.child1Id).as_scalar()
Когда я звоню Parent.query.order_by(Parent.child1Name).all()
, выражение работает так, как ожидалось.
Теперь для child2 и child3 будет установлен только один из них, поэтому, когда у родительской сущности установлен child2, child3-Нет и наоборот. Я хочу отсортировать родителя на основе имен child2 и child3, чтобы, например, если у меня есть родительская сущность с набором child2, и child2.name = «B» и другой родитель с набором child3 и child3.name = «A», второй родитель должен быть возвращен первым. Я попытался определить следующее гибридное свойство:
@hybrid_property def child2Or3Name(self): if self.child2Id is not None: return self.child2.name return self.child3.name @child2Or3Name.expression def child2Or3Name(cls): if cls.child2Id is not None: return select([Child2Model.name]).where(Child2Model.id == cls.child2Id).as_scalar() return select([Child3Model.name]).where(Child3Model.id == cls.child3Id).as_scalar()
Но когда я звоню Parent.query.order_by(Parent.child2Or3Name).all()
, данные возвращаются, но не в правильном порядке. Как я должен определить гибридное свойство и его выражение?
Ответ №1:
Найдено решение, выражение должно выглядеть так:
@child2Or3Name.expression def child2Or3Name(cls): s1 = select([Child2Model.name]).where(Child2Model.id == cls.child2Id) s2 = select([Child3Model.name]).where(Child3Model.id == cls.child3Id) return s1.union_all(s2).as_scalar()