简体   繁体   English

使用 python 将字典列表插入到 SQL 表中

[英]Insert a list of dictionaries into an SQL table using python

I'm making my first steps using python and sql databases and still am not sure which package to use and how.我正在使用 python 和 sql 数据库迈出第一步,但仍然不确定要使用哪个包以及如何使用。 I have a list with approx 300k dictionaries each with roughly about 20 keys.我有一个包含大约 30 万个字典的列表,每个字典大约有 20 个键。 These dicts shall be inserted into an SQL table.这些字典应插入到 SQL 表中。

In my opinion the advantahe of the list of dict approach is, that I explicitly name the columns in which I want to enter specific values.在我看来,dict 方法列表的优点是,我明确命名了要在其中输入特定值的列。 (It might be, that this is not a good approach) (这可能不是一个好方法)

Let me present a more specific example catching the essentials of my problem.让我举一个更具体的例子来说明我的问题的本质。 The table consists of three columns: ID (Integer), Price (Decimal), Type (string).该表由三列组成:ID(整数)、价格(十进制)、类型(字符串)。 Type supports null values.类型支持空值。

The keys of my dict have the same name and the list of dicts might look like this:我的 dict 的键具有相同的名称,并且 dict 列表可能如下所示:

lst = [{'ID':1, 'Price': '9.95', 'Type': None}, 
       {'ID':2, 'Price': '7.95', 'Type': 'Sports'}, 
       {'ID':3, 'Price': '4.95', 'Type': 'Tools'}, ...]

So the questions that arise are the following:所以出现的问题如下:

  1. Is the approach using dicts the right?使用 dicts 的方法正确吗? (Note that I have 20 columns) (请注意,我有 20 列)
  2. If yes/or no: How should one perform such a query efficiently?如果是/或否:应该如何有效地执行这样的查询?
  3. Is it necessary to convert the prices to Decimal and before the SQL statement, or can this be achieved 'on-the-fly'是否有必要在 SQL 语句之前将价格转换为十进制,或者可以“即时”实现
  4. Is the None value automatically converted to null, or is there extra work to be done? None 值是否自动转换为 null,或者是否有额外的工作要做?

Assuming you are using a Python Database API specification compliant database driver.假设您使用的是符合Python 数据库 API 规范的数据库驱动程序。

Type conversions (questions 3 and 4) should be handled by the database driver out-of-the-box.类型转换(问题 3 和 4)应该由开箱即用的数据库驱动程序处理。

As for the 2), there is executemany() :至于 2),有executemany()

cursor.executemany("""
    INSERT INTO 
        mytable
        (id, price, type)
    VALUES
        (%(id)s, %(price)s, %(type)s)
""", lst)
mydb = MySQLdb.connect(host='',    # your host_name
                       user='',    # your username
                       passwd='',  # your password
                       db=''       # your database
                       )
cur= mydb.cursor()
insert_query = "INSERT INTO table_name(feild_1,feild2,feild3) VALUES ( %(id)s, %(price)s, %(type)s);"
cur.executemany(insert_query, lst)
mydb.commit

Answers to your questions:回答您的问题:

  • No problem with using a list of dictionaries使用字典列表没问题
  • down below is the full application the handle your case下面是完整的应用程序处理你的情况
  • it is not necessary to convert the prices to Decimal, in this example in MySQL we declare price as decimal, but in the list, it was set as a string also as integer, but it's saved as decimal没有必要将价格转换为十进制,在这个例子中,在 MySQL 中我们将价格声明为十进制,但在列表中,它被设置为字符串也为整数,但它保存为十进制
  • The None value automatically converted to null None 值自动转换为 null
from tkinter import *
import mysql.connector as myConnector
from tkinter import messagebox
from mysql.connector import Error
def insert(table,lst):

    myList = listNestedDictForTblInsert(lst)
    print(myList)
    
    mySqlStr = f'INSERT INTO {table}(ID, Price, Type) VALUES(%s,%s,%s)' 
    val = myList
    print(mySqlStr)
    print(val)
    myDb = myConnector.connect(host='localhost',
                               database = "libraryDb2",
                               user='root',
                               password='dhso')
    try:
       myCursor = myDb.cursor()
       myCursor.executemany(mySqlStr, val)
       myDb.commit()
       messagebox.showinfo("show info", "Data is saved successfully")
    except Error as e:
       messagebox.showinfo("show info", "Data is not saved")

    myDb.close()
    myCursor.close()


def listNestedDictForTblInsert(data):
#Convert the list of dictionaries into list of tuples
   myList = []
   for i in range(len(data)):
      myList1 = []
      for value in (data[i].values()):
         myList1.append(value)
      myList1 = tuple(myList1)   
      myList.append(myList1)
   return myList
#Output myList:
#[('Ralph', 45), ('Betty', 50), ('Joey', 45), ('Heather', 25)]
           
root = Tk()

lst = [{'ID':1, 'price': 9.95, 'type': None}, 
       {'ID':2, 'Price': '7', 'type': 'Sports'}, 
       {'ID':3, 'Price': 4, 'Type': 'Tools'}]
table = 'test1'
root.title("Testing Part")
btn = Button(root, text = "Insert Dictionary in MYSQL Table", width = 30, command = lambda : insert(table, lst))
btn.pack()
root.mainloop

申请窗口

mysql 表 test1 存储在表中的数据

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM