Я работаю над проектом flask и застрял в проблеме, в которой я пытаюсь добавить оператор запроса в запрос в виде столбца.
Я перепробовал множество потенциальных решений, и самое близкое, что я нашел до сих пор, это add_columns()
, проблема в том, что это заставляет запрос возвращать кортеж с объектом модели, который я запрашивал, и является результатом оператора case , что я хочу, это просто объект модели, в котором есть результат регистра.
Вот упрощенный код, который показывает мою проблему
from flask import Flask
from sqlalchemy.sql.expression import case
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database.db"
db = SQLAlchemy(app)
class Image(db.Model):
__tablename__ = 'images'
id = db.Column(db.Integer, primary_key=True)
url = db.Column(db.Text)
model_id = db.Column(db.Integer)
db.create_all()
@app.route('/')
def hello_world():
image_ids = [1, 2, 3, 4, 5]
image_weights = [0.1, 0.4, 0.23232, 0.21, 0.001]
print(list(zip(image_ids, image_weights)))
case_statement = case(
[(uid == Image.id, weight) for uid, weight in zip(image_ids, image_weights)]
)
results = db.session.query(Image).add_columns(case_statement.label("weight")).filter(
Image.id.in_(image_ids)).order_by("weight")
print(results)
print(results.all())
return 'Hello World!'
if __name__ == '__main__':
app.run(debug=True)
, вывод print(results.statement.compile(compile_kwargs={"literal_binds": True}))
SELECT images.id,
images.url,
images.model_id,
CASE WHEN (images.id = 1) THEN 0.1 WHEN (images.id = 2) THEN 0.4 WHEN (images.id = 3) THEN 0.23232 WHEN (images.id = 4) THEN 0.21 WHEN (images.id = 5) THEN 0.001 END AS weight
FROM images
WHERE images.id IN (1, 2, 3, 4, 5)
ORDER BY weight;
вывод print(results.all())
[(<Image 5>, 0.001), (<Image 1>, 0.1), (<Image 4>, 0.21), (<Image 3>, 0.23232), (<Image 2>, 0.4)]
результат, который я ищу, это
[<Image 5>, <Image 1>, <Image 4>, <Image 3>, <Image 2>]
Одно простое решение для этого - просто go над каждым элементом в списке результатов и используйте setattr, чтобы установить вес атрибута объекта изображения для второго элемента в кортеже, но я не могу этого сделать, поскольку хочу создать функцию, которая возвращает объект запроса с фильтрами применяется не список объектов