首页 > 解决方案 > 如何在 SQLAlchemy UPDATE 调用中的函数中嵌入函数

问题描述

在 SQLAlchemy Core 中工作,我正在尝试创建一个 UPDATE 语句,该语句使用同一表中其他列中的值的 MD5 哈希填充列。我事先不知道列名是什么,但我想将每列中的值附加在一起,然后从中创建哈希值。这是我试图生成的 SQL 的 SET 子句的感觉......

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') ,因此,每行的哈希值都相同。如何让它实际使用查询中的列名而不是我提供的文字字符串?

我现在正在为 MySQL 写这篇文章,但是使用移植到其他数据库的 SQLAlchemy 函数而不是 MySQL 特定的函数会很棒。

标签: pythonsqlalchemy

解决方案


从表中查找实际列并将其解包为以下参数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)

推荐阅读