【问题标题】:How to update multiple rows with single MySQL query in python?如何在 python 中使用单个 MySQL 查询更新多行?
【发布时间】:2015-02-28 20:39:48
【问题描述】:
#!/usr/bin/python

# -*- coding: utf-8 -*-
import MySQLdb as mdb

con = mdb.connect('localhost', 'root', 'root', 'kuis')

with con:

    cur = con.cursor()
    cur.execute("UPDATE Writers SET Name = %s WHERE Id = %s ",
        ("new_value" , "3"))
    print "Number of rows updated:",  cur.rowcount


使用上面的代码,数据库 kuis 中表 Writers 的第三行值被更新为 new_value,输出将是 Number od rows updated: 1
我应该如何同时更新多行?

【问题讨论】:

  • 更改您的WHERE 语句以匹配多个条件?
  • 也许 cursor.execute('update sql ...', multi=True)?
  • @algosig,你想用"new_values" = 3更新多行,还是用不同的“new_value”更新多个sql?
  • @Anzel 我想更新第三行中的“tom”,即'3'和第四行中的“sam”,即'4',是否可以使用单个 cur.execute(. ..) 查询还是应该多次使用相同的命令?
  • 我的评论和@PeterMmm 的回答都对你有用

标签: python mysql mysql-python


【解决方案1】:

我必须写一个简单的供我使用。

sql='''INSERT INTO <Tabel Name> (column 1, column 2, ... , column N)
 VALUES (%s, %s, ..., %s) 
ON DUPLICATE KEY UPDATE column1=VALUES(column 1), column3=VALUES(column N)''' 

mycursor.executemany(sql, 数据)

data = ['第 1 列的值', '第 2 列的值', ... ,'第 N 列的值']

【讨论】:

    【解决方案2】:

    我不认为 mysqldb 可以同时处理多个 UPDATE 查询。

    但是您可以在末尾使用带有 ON DUPLICATE KEY UPDATE 条件的 INSERT 查询。

    为了易于使用和可读性,我编写了以下示例。

    import MySQLdb
    
    def update_many(data_list=None, mysql_table=None):
        """
        Updates a mysql table with the data provided. If the key is not unique, the
        data will be inserted into the table.
    
        The dictionaries must have all the same keys due to how the query is built.
    
        Param:
            data_list (List):
                A list of dictionaries where the keys are the mysql table
                column names, and the values are the update values
            mysql_table (String):
                The mysql table to be updated.
        """
    
        # Connection and Cursor
        conn = MySQLdb.connect('localhost', 'jeff', 'atwood', 'stackoverflow')
        cur = conn.cursor()
    
        query = ""
        values = []
    
        for data_dict in data_list:
    
            if not query:
                columns = ', '.join('`{0}`'.format(k) for k in data_dict)
                duplicates = ', '.join('{0}=VALUES({0})'.format(k) for k in data_dict)
                place_holders = ', '.join('%s'.format(k) for k in data_dict)
                query = "INSERT INTO {0} ({1}) VALUES ({2})".format(mysql_table, columns, place_holders)
                query = "{0} ON DUPLICATE KEY UPDATE {1}".format(query, duplicates)
    
            v = data_dict.values()
            values.append(v)
    
        try:
            cur.executemany(query, values)
        except MySQLdb.Error, e:
            try:
                print"MySQL Error [%d]: %s" % (e.args[0], e.args[1])
            except IndexError:
                print "MySQL Error: %s" % str(e)
    
            conn.rollback()
            return False
    
        conn.commit()
        cur.close()
        conn.close()
    

    一个衬垫的解释

    columns = ', '.join('`{}`'.format(k) for k in data_dict)
    

    与

    相同
    column_list = []
    for k in data_dict:
        column_list.append(k)
    columns = ", ".join(columns)
    

    这是一个使用示例

    test_data_list = []
    test_data_list.append( {'id' : 1, 'name' : 'Tech', 'articles' : 1 } )
    test_data_list.append( {'id' : 2, 'name' : 'Jhola', 'articles' : 8 } )
    test_data_list.append( {'id' : 3, 'name' : 'Wes', 'articles' : 0 } )
    
    update_many(data_list=test_data_list, mysql_table='writers')
    

    查询输出

    INSERT INTO writers (`articles`, `id`, `name`) VALUES (%s, %s, %s) ON DUPLICATE KEY UPDATE articles=VALUES(articles), id=VALUES(id), name=VALUES(name)
    

    值输出

    [[1, 1, 'Tech'], [8, 2, 'Jhola'], [0, 3, 'Wes']]
    

    【讨论】:

    • 实际上有一个,它在您的答案上方进行了解释。希望你也从中受益;)
    • 这个答案为我节省了很多时间。我正在使用第一个答案更新一个巨大的表格,这需要几个小时。对于相同的查询,使用 INSERT ON DUPLICATE KEY 只需大约一分钟。原因在mysql页面上有解释:“大多数情况下,executemany()方法会遍历参数序列,每次将当前参数传递给execute()方法。”
    • 这个答案对我有用。我将它调整为与 mysql.connector 一起使用。对于 Python 3.8,我还必须将 `data_dict.values()` 更改为 list( data_dict.values())。我还需要包含所有列(不确定是否由于数据库限制而需要这样做?)。我在一分钟内对远程服务器进行了大约 50K 的数据转换和更新。现在是一些大桌子。
    【解决方案3】:

    您可能正在寻找cursor.executemany。

    cur.executemany("UPDATE Writers SET Name = %s WHERE Id = %s ",
            [("new_value" , "3"),("new_value" , "6")])
    

    【讨论】:

    • 我得到了结果,但是为什么更新的行数仍然相同,即 1 当我更新两个字段时应该是 2?
    • @algosig,那是因为在 execute 级别上没有数据库提交,直到您执行conn.commit(),这就是您要求 executemany 的全部意义 不是吗?
    • @PeterMmm,谢谢。你能帮我查询一下吗? Qry - "更新 mytable SET status = 'new status' where id in ()"
    • @John cur.executemany("Update mytable SET status = %s where id = %s",[("new status" , "3"),("new status" , "6")])
    • 感兴趣的各方仅供参考 - 如果您遇到语法错误但无法弄清楚原因,请尝试使用引号字符(甚至删除它们)。我对字符串值使用单引号,但切换到双引号甚至没有引号似乎开始起作用(不确定它是否值得一个新问题)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-28
    相关资源
    最近更新 更多