Как вставить Pandas Dataframe в MySql, используя PyMySQL - PullRequest
1 голос
/ 04 октября 2019

У меня есть 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()

Спасибо.

Ответы [ 3 ]

1 голос
/ 04 октября 2019

Попробуйте использовать SQLALCHEMY для создания движка, который вы можете использовать позже с функцией pandas df.to_sql. Эта функция записывает строки из pandas dataframe в базу данных 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

1 голос
/ 04 октября 2019

Быстрее отправить файл на сервер 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)
1 голос
/ 04 октября 2019

Возможные улучшения.

  • удаление или отключение индексов для таблиц
  • Извлечение коммита из цикла

Теперь попробуйте изагрузить данные.

Создайте файл CSV и загрузите, используя ** LOAD DATA INFILE ** - это будет выдано из mysql.

...