Как встроить функцию в функцию в вызове UPDATE SQLAlchemy - PullRequest
1 голос
/ 11 апреля 2020

Работая в SQLAlchemy Core, я пытаюсь создать оператор UPDATE, который заполняет столбец MD5 га sh из значений в других столбцах той же таблицы. Я не знаю заранее, какими будут имена столбцов, но я хочу добавить значение в каждом столбце вместе, а затем создать значение ha sh из этого. Вот смысл предложения SET для SQL, который я пытаюсь сгенерировать ...

SET master_key = MD5(CONCAT(last_name, first_name))

Этот оператор обновления может потенциально включать миллионы строк, поэтому я хотел бы, чтобы работа была выполнена в базе данных, вместо того, чтобы перенести набор данных в Python, применить новое значение и затем записать его обратно в БД.

Вот мой Python код ...

    stmt = self.tbl.update().where(self.tbl.c.master_key==None).\
        values({'master_key': func.MD5(concat(key_col_names))})
    qry_engine.execute(statement=stmt)

key_col_names - это строка, содержащая список имен столбцов, разделенных запятыми (например, 'last_name, first_name').

SQLAlchemy генерирует следующее, где у меня есть функция MD5 : MD5 ('last_name, first_name') и, следовательно, значение ha sh выходит одинаковым в каждой строке. Как заставить это фактически использовать имена столбцов в запросе, а не литеральную строку, которую я предоставляю?

Я пишу это для MySQL прямо сейчас, но было бы здорово сделать он использует функции SQLAlchemy, которые переносятся на другие базы данных, а не MySQL -specifi c.

1 Ответ

1 голос
/ 11 апреля 2020

Поиск фактических столбцов из вашей таблицы и распаковка в качестве аргументов для CONCAT():

key_cols = [self.tbl.c[name.strip()] for name in key_col_names.split(",")]
stmt = self.tbl.update().where(self.tbl.c.master_key==None).\
        values({'master_key': func.MD5(func.concat(*key_cols))})
qry_engine.execute(statement=stmt)

Если столбцы, о которых идет речь, имеют строковый тип, используйте оператор + в Python для создания конкатенации выражение:

key_cols = [self.tbl.c[name.strip()] for name in key_col_names.split(",")]
# This is a bit of a hack and effectively the same as using reduce and operator.add.
# Another option would be to use a good old for-loop to reduce.
key_col_cat = sum(key_cols)
stmt = self.tbl.update().where(self.tbl.c.master_key==None).\
        values({'master_key': func.MD5(key_col_cat)})
qry_engine.execute(statement=stmt)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...