2017-02-06 13 views
0

我有一個數據庫結構如下所示:如何使用func作爲sqlalchemy中的值執行批量更新?

當前值

| file_id | file_path | 
+---------+-------------+ 
| 1  | path\test | 
+---------+-------------+ 
| 2  | path\test2 | 
+---------+-------------+ 
| 2  | path\test3 | 
+---------+-------------+ 

使用sqlalchemy,我試圖用func.replace來代替反斜槓在file_path列正斜槓。

期望值

| file_id | file_path | 
+---------+-------------+ 
| 1  | path/test | 
+---------+-------------+ 
| 2  | path/test2 | 
+---------+-------------+ 
| 3  | path/test3 | 
+---------+-------------+ 

至於現在,我單獨更新每一行,我能夠進行更換,沒有任何問題

from sqlalchemy import Table, MetaData, Column, Integer, String, func, create_engine 

table = Table('file_table', MetaData(), Column('id', Integer), Column('file_path', String)) 
file_ids = [1, 2, 3] 

connection = create_engine('connections_string') 
cursor = connection.connect() 

for file_id in file_ids: 
    q_ = table.update().values({'file_path': func.replace(table.c.file_path, '\\', '/')}).where(table.c.file_id == file_id) 
    cursor.execute(query) 

cursor.close() 

而不是單獨做的每一次更新,我試圖將其轉換爲批量更新。我以前做過批量更新,下面是我通常會執行一個

scripts = [{'file_path': 'new_column_value', 'bk_file_id': f} for f in [1,2,3]] 
q_ = table.update().where(table.c.file_id == bindparam('bk_file_id')) 
cursor.execute(q_, scripts) 

上述工作正常,但執行回溯

func.replace

scripts = [{'file_path': func.replace(table.c.file_path, '\\', '/'), 'bk_file_id': f} for f in [1,2,3]] 
q_ = table.update().where(table.c.file_id == bindparam('bk_file_id')) 
cursor.execute(q_, scripts) 

當它不工作

Traceback (most recent call last): File "bulk_update.py", line 15, in <module> cursor.execute(q_,scripts) File "C:\Python35\lib\site-packages\sqlalchemy\engine\base.py", line 914, in execute return meth(self, multiparams, params) File "C:\Python35\lib\site-packages\sqlalchemy\sql\elements.py", line 323, in _execute_on_connection return connection._execute_clauseelement(self, multiparams, params) File "C:\Python35\lib\site-packages\sqlalchemy\engine\base.py", line 1010, in _execute_clauseelement compiled_sql, distilled_params File "C:\Python35\lib\site-packages\sqlalchemy\engine\base.py", line 1146, in _execute_context context) File "C:\Python35\lib\site-packages\sqlalchemy\engine\base.py", line 1344, in _handle_dbapi_exception util.reraise(*exc_info) File "C:\Python35\lib\site-packages\sqlalchemy\util\compat.py", line 186, in reraise raise value File "C:\Python35\lib\site-packages\sqlalchemy\engine\base.py", line 1116, in _execute_context context) File "C:\Python35\lib\site-packages\sqlalchemy\dialects\mysql\mysqldb.py", line 95, in do_executemany rowcount = cursor.executemany(statement, parameters) File "C:\Python35\lib\site-packages\pymysql\cursors.py", line 195, in executemany self.rowcount = sum(self.execute(query, arg) for arg in args) File "C:\Python35\lib\site-packages\pymysql\cursors.py", line 195, in <genexpr> self.rowcount = sum(self.execute(query, arg) for arg in args) File "C:\Python35\lib\site-packages\pymysql\cursors.py", line 164, in execute query = self.mogrify(query, args) File "C:\Python35\lib\site-packages\pymysql\cursors.py", line 143, in mogrify query = query % self._escape_args(args, conn) File "C:\Python35\lib\site-packages\pymysql\cursors.py", line 123, in _escape_args return dict((key, conn.literal(val)) for (key, val) in args.items()) File "C:\Python35\lib\site-packages\pymysql\cursors.py", line 123, in <genexpr> return dict((key, conn.literal(val)) for (key, val) in args.items()) File "C:\Python35\lib\site-packages\pymysql\connections.py", line 800, in literal return self.escape(obj, self.encoders) File "C:\Python35\lib\site-packages\pymysql\connections.py", line 793, in escape return escape_item(obj, self.charset, mapping=mapping) File "C:\Python35\lib\site-packages\pymysql\converters.py", line 27, in escape_item val = encoder(val, mapping) File "C:\Python35\lib\site-packages\pymysql\converters.py", line 110, in escape_unicode return u"'%s'" % _escape_unicode(value) File "C:\Python35\lib\site-packages\pymysql\converters.py", line 73, in _escape_unicode return value.translate(_escape_table) File "C:\Python35\lib\site-packages\sqlalchemy\sql\elements.py", line 738, in __getattr__ key) AttributeError: Neither 'Function' object nor 'Comparator' object has an attribute 'translate' 

如何解決此錯誤以使用func執行批量更新?

+0

錯誤消息引用了一個屬性'translate'地方,但它不會出現在代碼你提供了。你能給我們完整的堆棧跟蹤嗎? – univerio

+0

@univerio全部引用添加 – Wondercricket

回答

1

您的問題來自executemany表格values不支持表達式,但對於批量更新,您不應該使用executemany表單。

基本上你做之前是:

UPDATE file_table SET file_path = replace(file_path, '\\', '/') WHERE file_id = 1; 
UPDATE file_table SET file_path = replace(file_path, '\\', '/') WHERE file_id = 2; 
UPDATE file_table SET file_path = replace(file_path, '\\', '/') WHERE file_id = 3; 

而你試圖模仿你的批量更新的精確查詢。爲什麼不直接運行一個查詢呢?

UPDATE file_table SET file_path = replace(file_path, '\\', '/') WHERE file_id IN (1, 2, 3); 

而且辦法做到這一點在SQLAlchemy的是相當多的你在做什麼之前:

table.update().values({'file_path': func.replace(table.c.file_path, '\\', '/')}).where(table.c.file_id.in_(file_ids)) 
+0

感謝您的信息!無論如何,我最終轉向了'in_',但很高興知道'executemany'中不支持表達式 – Wondercricket

相關問題