Я точно не знал, как это сформулировать, поэтому я сделаю все возможное.
По сути, я пытаюсь выяснить, содержит ли какой-либо столбец Mutable JSONB в моей строке пользователя "own_products" какое-либопродукты, которые не являются демонстрационными.
Позвольте мне немного распаковать это:
Столбец моей модели выглядит следующим образом -
owned_products = Column(MutableDict.as_mutable(JSONB), default=default_products)
Где мой класс MutableDict разорван прямо отсюда- Отслеживание мутаций
и мой словарь всегда выглядит так:
default_products = {
'product-1': False,
'product-1-demo': False,
'product-2': False,
'product-3': False,
'product-3-demo': False,
... ... so on and so forth
}
Это работает очень хорошо и позволяет мне добавить /обновлять / фильтровать продукты, как если бы это был обычный словарь.Но я недавно узнал о @hybrid_property декораторах, и я хотел бы включить это в свою модель, предоставив такие вещи, как User.owns_any_paid_product или User.owns_any_ {x-product-range}, чтобы сортировка пользователей по продуктамбыстрее.
После первой попытки это застряло у меня, вот что у меня есть до сих пор
@hybrid_property
def owns_any_paid(self):
for product in self.owned_products:
if (product in paid_products) and (self.owned_products[product]):
return True
return False
@owns_any_paid.expression
def owns_any_paid(cls):
return cls.??????
Мне действительно трудно найти cls, которые бы удовлетворили это.В прошлом я знал, что мог отфильтровать этот диктат, выполнив session.query(User).filter(User.owned_products.contains({k, v}))
Но в этом режиме мне пришлось создать список таких фильтров (скажем, например, я хотел, чтобы все, кто не имеет ничего, кроме демонстраций продуктов):
filter_list = [~User.owned_products.contains({k,v}) for k, v in paid_products.items()]
session.query(User).filter(*filter_list)
И я не имею ни малейшего понятия о том, как я могу вернуть это как действительный cls для моего hybrid_property.expression.
У кого-нибудь есть какие-либо советы по этому поводу?
РЕДАКТИРОВАТЬ --------------
Для тех, кто находит это.Мне удалось использовать функциональность case () в sqlalchemy, чтобы исправить это ... в сочетании со случайной удачей.
Фрагмент кода ниже:
@owns_any_paid.expression
def owns_any_paid(cls):
return case([(cls.owned_products[k].astext.cast(Boolean), v) for k,v in paid_products.items()])