Инструкция SqlAlchemy Update, связывающая всю строку как значенияPython

Программы на Python
Ответить
Anonymous
 Инструкция SqlAlchemy Update, связывающая всю строку как значения

Сообщение Anonymous »

Я не уверен, возможно ли это на основании документации, но у меня есть текстовый запрос, который обновляет все значения строк при каждом запуске. Первоначально это делалось через Oracle и его курсор, передавая строку и привязывая ее к параметрам. Мы переходим на postgres и sqlalchemy, поэтому, пытаясь преобразовать некоторые из этих вещей, я сталкиваюсь с проблемой, из-за которой мне приходится привязывать каждый отдельный параметр каждый раз, когда я вызываю запрос, иначе в зависимости от того, что я пробовал, произойдет ошибка.
Запрос:

Код: Выделить всё

update_qc_sod = text(f"""
update {QcSodTable.__table__.fullname}
stn_ops = :stn_ops,
precip_trace = :precip_trace,
precip = :precip,
precip_period = :precip_period,
temp_max = :temp_max,
temp_min = :temp_min
where platformid = :platformid and
trim(networktype) = :networktype and
datetime = :datetime
""")
Я пытался выполнить следующие способы:
(обновляйте только те значения, которые были изменены в этом цикле)

Код: Выделить всё

connection.execute(queries.update_qc_sod.bindparams(qc_flag=qc_sod_new_row.QcSodTable.qc_flag, remarks=qc_sod_new_row.QcSodTable.remarks))
(Попробуйте обновить все строки)

Код: Выделить всё

connection.execute(queries.update_qc_sod.bindparams(qc_sod_new_row))
(Попробуйте передать в качестве параметров)

Код: Выделить всё

connection.execute(queries.update_qc_sod, qc_sod_new_row)
У меня есть довольно много мест, где это существует, и было бы гораздо проще использовать его как есть, вместо того, чтобы делать запрос для каждого из них с правильными параметрами только для привязки. Я мог бы вручную добавить каждый параметр для привязки, но это сделало бы его невероятно уродливым и большим. Если это единственный способ, то я попытаюсь это сделать, но если есть лучший и более чистый способ передать всю строку в качестве параметра обновления, это было бы фантастически.
Изменить:
Итак, чтобы прояснить, что я пытаюсь сделать: у меня есть оператор select, который использует объединение для захвата строк из QcSodTable. После этого результат проходит серию проверок качества, чтобы убедиться, что все данные действительны. Если данные необходимо изменить, они будут вставлены сразу после этого, чтобы они были готовы к другим проверкам в дальнейшем, которым может потребоваться использовать эти данные.

Код: Выделить всё

qc_sod_row = connection.execute(queries.get_qc_sod_data).all()[0][0]
Вот краткий пример одной из проверок контроля качества:

Код: Выделить всё

def check_datetimes(connection, qc_sod_row, algorithm, is_good):
"""
if local_time or date does not exist, then add remarks and
add alg flag of C00/01
"""
qc_sod_new_row = copy.deepcopy(qc_sod_row)

if not is_good:
qc_sod_new_row.remarks = utils.update_remarks(qc_sod_row.remarks, algorithm)
qc_sod_new_row.qc_flag = "F"
# Update the QC_SOD table with new values
diction = utils.bind_qc_sod(queries.update_qc_sod, qc_sod_new_row)
connection.execute(queries.update_qc_sod, diction)

return qc_sod_new_row
Ошибка, с которой я сталкиваюсь, возникает во время соединения.execute, когда я пытаюсь передать параметры, которые вызывают множество проблем в зависимости от того, как я пытаюсь связать параметры.
Вышеупомянутая переменная словаря представляет собой словарь каждого имени строки и параметра, который я хочу связать

Код: Выделить всё

    diction = dict(
stn_ops= qc_sod.stn_ops,
precip_trace= qc_sod.precip_trace,
precip= qc_sod.precip,
precip_period= qc_sod.precip_period,
temp_max= qc_sod.temp_max,
temp_min= qc_sod.temp_min,
wind_gust_dir= qc_sod.wind_gust_dir
)
Итак, в приведенном выше примере примечания будут объединяться с новыми примечаниями и обновлять qc_flag. Все остальные данные останутся прежними, поэтому я хочу обновить только эти поля, но сам запрос используется и в других областях для обновления других столбцов (precip, temp_max и т. д.).
Вот как это делалось ранее с помощью библиотеки OracleCX:

Код: Выделить всё

def chk_localtime(qc_sod_row, time_conv, sod_connection):
ALG_FLAG = "C00"
qc_sod_row_new = qc_sod_row.copy()

if not local_time_check(time_conv):
cursor_sod = sod_connection.cursor()

qc_sod_row_new["REMARKS"] = utils.update_remarks(qc_sod_row, ALG_FLAG)
qc_sod_row_new["QC_FLAG"] = "F"

#Update the QC_SOD table with new values
cursor_sod.execute(qc_sod_queries.update_qc_sod, qc_sod_row_new)

cursor_sod.close()

return qc_sod_row_new
По сути, у меня есть строка, которая будет обновляться в некоторых столбцах, а не в других, я хочу обновить столбцы, которые были изменены. Поскольку столбец, который может измениться, всегда различен, было бы здорово просто передать новую, обновленную строку вместе со всеми параметрами и просто обновить то, что было изменено, если это имеет смысл.
Я еще попробовал использовать SqlAlchemy для создания оператора:

Код: Выделить всё

update_qc_sod = (
update(QcSodTable)
.where(
QcSodTable.platformid == bindparam("platformid"),
func.trim(QcSodTable.networktype) == bindparam("networktype"),
QcSodTable.datetime == bindparam("datetime")
)
.values(
stn_ops=bindparam("stn_ops"),
precip_trace=bindparam("precip_trace"),
precip=bindparam("precip"),
precip_period=bindparam("precip_period"),
temp_max=bindparam("temp_max"),
temp_min=bindparam("temp_min"),
wind_gust_dir=bindparam("wind_gust_dir"),
)
)
Надеюсь, это внесет некоторую ясность, если нет, я могу добавить дополнительную информацию/примеры

Подробнее здесь: https://stackoverflow.com/questions/798 ... -as-values
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»