Я пытаюсь выполнить необработанный запрос на обновление, используя psycopg2 в django. Код следующий:
from django.db import connection
from psycopg2 import sql
model_instances_to_update = []
for model_instance in models_queryset:
model_instances_to_update.append(
sql.Identifier(
f"({id},{col_1_value},{col_2_value},{col_3_value},{col_4_value})"
)
)
model_instance_query_values_string = sql.SQL(", ").join(model_instances_to_update)
model_instance_sql_params = {"updated_model_instance_values": model_instance_query_values_string}
model_instance_update_query = sql.SQL(
"""
UPDATE {table} AS model_table SET
col_1 = model_table_new.col_1,
col_2 = model_table_new.col_2,
col_3 = model_table_new.col_3,
col_4 = model_table_new.col_4
FROM (VALUES (%(updated_model_instance_values)s)) AS model_table_new(id, col_1, col_2, col_3, col_4)
WHERE model_table.id = model_table_new.id;
"""
).format(
table=sql.Identifier("table_name"),
)
with connection.cursor() as cursor:
cursor.execute(
model_instance_update_query,
params=model_instance_sql_params,
)
Но когда я пытаюсь выполнить этот запрос, я получаю следующую ошибку:
TypeError: "object of type 'Composed' has no len()"
Что я здесь делаю не так и как это исправить?
ОБНОВЛЕНИЕ
Сейчас я прохожу список кортежей непосредственно в курсоре.execute. Я добавил заполнители в строку объекта SQL, но по-прежнему получаю ту же ошибку.
for model_instance in models_queryset:
model_instances_to_update.append(
(
id,
col_1_value,
col_2_value,
col_3_value,
col_4_value
)
)
colList = ["id", "col_1", "col_2", "col_3", "col_4"]
model_instance_update_query = sql.SQL(
"""
UPDATE {table} AS model_table SET
col_1 = model_table_new.col_1,
col_2 = model_table_new.col_2,
col_3 = model_table_new.col_3,
col_4 = model_table_new.col_4
FROM (VALUES ({records_list_template})) AS model_table_new(id, col_1, col_2, col_3, col_4)
WHERE model_table.id = model_table_new.id;
"""
).format(
table=sql.Identifier("table_name"),
records_list_template=sql.SQL(", ").join(
sql.Placeholder() * len(colList)
),
)
with connection.cursor() as cursor:
cursor.execute(
model_instance_update_query,
model_instances_to_update,
)
Подробнее здесь: https://stackoverflow.com/questions/784 ... sql-object