【问题标题】:How to insert a Pandas Dataframe into MySql using PyMySQL如何使用 PyMySQL 将 Pandas 数据框插入 MySql
【发布时间】:2020-02-02 13:05:20
【问题描述】:

我有一个 DataFrame,它有大约 30,000 多行和 150 多列。所以,目前我正在使用以下代码将数据插入 MySQL。但由于它一次读取一行,因此将所有行插入 MySql 需要花费太多时间。

有什么方法可以一次或分批插入所有行?这里的限制是我只需要使用 PyMySQL,我不能安装任何其他库。

import pymysql
import pandas as pd

# Create dataframe
data = pd.DataFrame({
    'book_id':[12345, 12346, 12347],
    'title':['Python Programming', 'Learn MySQL', 'Data Science Cookbook'],
    'price':[29, 23, 27]
})


# Connect to the database
connection = pymysql.connect(host='localhost',
                         user='root',
                         password='12345',
                         db='book')


# create cursor
cursor=connection.cursor()

# creating column list for insertion
cols = "`,`".join([str(i) for i in data.columns.tolist()])

# Insert DataFrame recrds one by one.
for i,row in data.iterrows():
    sql = "INSERT INTO `book_details` (`" +cols + "`) VALUES (" + "%s,"*(len(row)-1) + "%s)"
    cursor.execute(sql, tuple(row))

    # the connection is not autocommitted by default, so we must commit to save our changes
    connection.commit()

# Execute query
sql = "SELECT * FROM `book_details`"
cursor.execute(sql)

# Fetch all the records
result = cursor.fetchall()
for i in result:
    print(i)

connection.close()

谢谢。

【问题讨论】:

标签: python mysql pandas dataframe pymysql


【解决方案1】:

尝试使用 SQLALCHEMY 创建引擎,而不是稍后使用 pandas df.to_sql 函数。此函数将行从 pandas 数据帧写入 SQL 数据库,它比迭代 DataFrame 和使用 MySql 游标快得多。

您的代码将如下所示:

import pymysql
import pandas as pd
from sqlalchemy import create_engine

# Create dataframe
data = pd.DataFrame({
    'book_id':[12345, 12346, 12347],
    'title':['Python Programming', 'Learn MySQL', 'Data Science Cookbook'],
    'price':[29, 23, 27]
})

db_data = 'mysql+mysqldb://' + 'root' + ':' + '12345' + '@' + 'localhost' + ':3306/' \
       + 'book' + '?charset=utf8mb4'
engine = create_engine(db_data)

# Connect to the database
connection = pymysql.connect(host='localhost',
                         user='root',
                         password='12345',
                         db='book')    

# create cursor
cursor=connection.cursor()
# Execute the to_sql for writting DF into SQL
data.to_sql('book_details', engine, if_exists='append', index=False)    

# Execute query
sql = "SELECT * FROM `book_details`"
cursor.execute(sql)

# Fetch all the records
result = cursor.fetchall()
for i in result:
    print(i)

engine.dispose()
connection.close()

您可以在pandas doc 中查看此函数的所有选项

【讨论】:

    【解决方案2】:

    将文件推送到 SQL 服务器并让服务器管理输入会更快。

    所以首先将数据推送到 CSV 文件中。

    data.to_csv("import-data.csv", header=False, index=False, quoting=2, na_rep="\\N")
    

    然后立即将其加载到 SQL 表中。

    sql = "LOAD DATA LOCAL INFILE \'import-data.csv\' \
        INTO TABLE book_details FIELDS TERMINATED BY \',\' ENCLOSED BY \'\"\' \
        (`" +cols + "`)"
    cursor.execute(sql)
    

    【讨论】:

      【解决方案3】:

      可能的改进。

      • 删除或禁用表上的索引
      • 让提交脱离循环

      现在尝试加载数据。

      生成一个 CSV 文件并使用 ** LOAD DATA INFILE ** 加载 - 这将在 mysql 中发出。

      【讨论】:

        猜你喜欢
        • 2019-11-24
        • 2016-10-04
        • 2019-07-13
        • 2021-09-14
        • 2018-10-14
        • 2017-12-30
        • 2013-12-10
        • 2019-09-06
        • 2017-06-11
        相关资源
        最近更新 更多