【问题标题】:Export pandas Dataframe or numpy array to MySQL将 pandas Dataframe 或 numpy 数组导出到 MySQL
【发布时间】:2017-08-25 17:35:39
【问题描述】:

我正在使用 python 将一个大矩阵(形状约为 3000 * 3000)导出到 MySQL。

现在我正在使用 MySQLdb 来插入这些值,但它太麻烦而且效率太低。这是我的代码:

# -*- coding:utf-8 -*-


import MySQLdb
import numpy as np
import pandas as pd
import time


def feature_to_sql_format(df):
    df = df.fillna(value='')
    columns = list(df.columns)
    index = list(df.index)
    index_sort = np.reshape([[int(i)] * len(columns) for i in index], (-1)).tolist()
    columns_sort = (columns * len(index))
    values_sort = df.values.reshape(-1).tolist()
    return str(zip(index_sort, columns_sort, values_sort))[1: -1].replace("'NULL'", 'NULL')


if __name__ == '__main__':
    t1 = time.clock()
    df = pd.read_csv('C:\\test.csv', header=0, index_col=0)
    output_string = feature_to_sql_format(df)
    sql_CreateTable = 'USE derivative_pool;DROP TABLE IF exists test1;' \
                      'CREATE TABLE test1(date INT NOT NULL, code VARCHAR(12) NOT NULL, value FLOAT NULL);'
    sql_Insert = 'INSERT INTO test (date,code,value) VALUES ' + output_string + ';'
    con = MySQLdb.connect(......)
    cur = con.cursor()
    cur.execute(sql_CreateTable)
    cur.close()
    cur = con.cursor()
    cur.execute(sql_Insert)
    cur.close()
    con.commit()
    con.close()
    t2 = time.clock()
    print t2 - t1

它总共消耗大约 274 秒。

我想知道是否有更简单的方法可以做到这一点,我想到了将矩阵导出到csv然后使用LOAD DATA INFILE来导入,但它也太复杂了。

我注意到在pandas文档中pandas dataframe有一个函数to_sql,在version 0.14你可以将'flavor'设置为'mysql',即:

df.to_sql(con=con, name=name, flavor='mysql')

但是现在我的pandas版本是0.19.2,味道也降到只有'sqlite'了……而且我还在尝试使用

df.to_sql(con=con, name=name, flavor='sqlite')

它给了我一个错误。

有什么方便的方法吗?

【问题讨论】:

标签: mysql python-2.7 pandas mysql-python


【解决方案1】:

以后的 pandas 版本支持 SQLalchemy 连接器,而不是 flavor = "mysql"

首先,安装依赖:

pip install mysql-connector-python-rf==2.2.2
pip install MySQL-python==1.2.5
pip install SQLAlchemy==1.1.1

然后创建引擎:

from sqlalchemy import create_engine
connection_string= "mysql+mysqlconnector://root:@localhost/MyDatabase"
engine = create_engine(connection_string)

那么你可以使用df.to_sql(...):

df.to_sql('MyTable', engine)

您可以在 MYSQL 中执行以下操作来加快数据加载速度:

SET FOREIGN_KEY_CHECKS = 0;
SET UNIQUE_CHECKS = 0;
SET SESSION tx_isolation='READ-UNCOMMITTED';
SET sql_log_bin = 0;
#LOAD DATA LOCAL INFILE....
SET UNIQUE_CHECKS = 1;
SET FOREIGN_KEY_CHECKS = 1;
SET SESSION tx_isolation='READ-REPEATABLE';

【讨论】:

  • 谢谢它有效,但问题是我试过了,它需要更长的时间!有没有办法缩短这个过程?我的 csv 大约是 3000 * 3000,它只需要 100M 作为 csv 格式文件。我不明白为什么要花这么长时间...
  • @DirkPaul 您的 CSV 有 3000 行和 3000 列?
  • 是的,但是对于 SQL 来说太大了,所以我必须用 (row_number, column_number, value) 把它变成一维的
  • 这应该不会花费太长时间......不过,您可以采取一些措施来加快 mysql 加载速度。见编辑。
  • 非常感谢~让我试试
猜你喜欢
  • 2019-03-12
  • 2018-01-18
  • 2019-08-04
  • 2020-02-10
  • 2021-01-16
  • 1970-01-01
  • 2020-11-09
  • 1970-01-01
  • 2021-04-24
相关资源
最近更新 更多