【问题标题】:How to insert pandas dataframe via mysqldb into database?如何通过mysqldb将熊猫数据框插入数据库?
【发布时间】:2013-05-04 19:01:54
【问题描述】:

我可以从 python 连接到我的本地 mysql 数据库,我可以创建、选择和插入单独的行。

我的问题是:我可以直接指示 mysqldb 获取整个数据帧并将其插入现有表中,还是需要遍历行?

在任何一种情况下,对于具有 ID 和两个数据列以及匹配数据框的非常简单的表,python 脚本会是什么样子?

【问题讨论】:

  • 您需要使用 mysqldb,还是可以使用其他 MySQL 连接器?

标签: python mysql pandas mysql-python


【解决方案1】:

更新:

现在有一个to_sql 方法,这是执行此操作的首选方法,而不是write_frame

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

另请注意:pandas 0.14 中的语法可能会发生变化...

您可以设置与MySQLdb的连接:

from pandas.io import sql
import MySQLdb

con = MySQLdb.connect()  # may need to add some other options to connect

write_frameflavor设置为'mysql'表示可以写入mysql:

sql.write_frame(df, con=con, name='table_name_for_df', 
                if_exists='replace', flavor='mysql')

参数if_exists告诉pandas如果表已经存在如何处理:

if_exists: {'fail', 'replace', 'append'},默认'fail'
fail:如果表存在,什么也不做。
replace: 如果表存在,删除它,重新创建它,然后插入数据。
append:如果表存在,插入数据。如果不存在则创建。

虽然 write_frame docs 目前建议它只适用于 sqlite,但似乎支持 mysql,实际上有相当多的 mysql testing in the codebase

【讨论】:

【解决方案2】:

Andy Hayden 提到了正确的函数 (to_sql)。在这个答案中,我将给出一个完整的示例,我使用 Python 3.5 进行了测试,但也应该适用于 Python 2.7(和 Python 3.x):

首先,让我们创建数据框:

# Create dataframe
import pandas as pd
import numpy as np

np.random.seed(0)
number_of_samples = 10
frame = pd.DataFrame({
    'feature1': np.random.random(number_of_samples),
    'feature2': np.random.random(number_of_samples),
    'class':    np.random.binomial(2, 0.1, size=number_of_samples),
    },columns=['feature1','feature2','class'])

print(frame)

这给出了:

   feature1  feature2  class
0  0.548814  0.791725      1
1  0.715189  0.528895      0
2  0.602763  0.568045      0
3  0.544883  0.925597      0
4  0.423655  0.071036      0
5  0.645894  0.087129      0
6  0.437587  0.020218      0
7  0.891773  0.832620      1
8  0.963663  0.778157      0
9  0.383442  0.870012      0

将此数据框导入 MySQL 表:

# Import dataframe into MySQL
import sqlalchemy
database_username = 'ENTER USERNAME'
database_password = 'ENTER USERNAME PASSWORD'
database_ip       = 'ENTER DATABASE IP'
database_name     = 'ENTER DATABASE NAME'
database_connection = sqlalchemy.create_engine('mysql+mysqlconnector://{0}:{1}@{2}/{3}'.
                                               format(database_username, database_password, 
                                                      database_ip, database_name))
frame.to_sql(con=database_connection, name='table_name_for_df', if_exists='replace')

一个技巧是MySQLdb 不适用于 Python 3.x。所以我们改用mysqlconnector,可能是installed,如下:

pip install mysql-connector==2.1.4  # version avoids Protobuf error

输出:

请注意,to_sql 会创建表以及如果数据库中尚不存在列。

【讨论】:

  • \AppData\Roaming\Python\Python37\site-packages\sqlalchemy\engine\url.py in __init__(self, drivername, username, password, host, port, database, query) 69 self.host = host 70 if port is not None: ---> 71 self.port = int(port) 72 else: 73 self.port = None ValueError: invalid literal for int() with base 10: '' 端口号问题,如何提及端口
  • @pyd 包含端口的字符串格式如下:'mysql+mysqldb://{user}:{password}@{server}:{port}/{database}'.format(user='<user>', password='<password>', server='<server>', port='<port>', database=<'database'>)
【解决方案3】:

你可以使用 pymysql 来做到这一点:

例如,假设您有一个 MySQL 数据库,其中包含下一个用户、密码、主机和端口,并且您想写入数据库“data_2”,如果它已经存在或不存在

import pymysql
user = 'root'
passw = 'my-secret-pw-for-mysql-12ud'
host =  '172.17.0.2'
port = 3306
database = 'data_2'

如果您已经创建了数据库

conn = pymysql.connect(host=host,
                       port=port,
                       user=user, 
                       passwd=passw,  
                       db=database,
                       charset='utf8')

data.to_sql(name=database, con=conn, if_exists = 'replace', index=False, flavor = 'mysql')

如果您没有创建数据库,当数据库已经存在时也有效:

conn = pymysql.connect(host=host, port=port, user=user, passwd=passw)

conn.cursor().execute("CREATE DATABASE IF NOT EXISTS {0} ".format(database))
conn = pymysql.connect(host=host,
                       port=port,
                       user=user, 
                       passwd=passw,  
                       db=database,
                       charset='utf8')

data.to_sql(name=database, con=conn, if_exists = 'replace', index=False, flavor = 'mysql')

类似的线程:

  1. Writing to MySQL database with pandas using SQLAlchemy, to_sql
  2. Writing a Pandas Dataframe to MySQL

【讨论】:

  • name 参数应该是表名,而不是数据库名。
  • to_sql 的风味 kwarg 不再被允许。
【解决方案4】:

Python 2 + 3

先决条件

  • 熊猫
  • MySQL 服务器
  • sqlalchemy
  • pymysql:纯python mysql客户端

代码

from pandas.io import sql
from sqlalchemy import create_engine

engine = create_engine("mysql+pymysql://{user}:{pw}@localhost/{db}"
                       .format(user="root",
                               pw="your_password",
                               db="pandas"))
df.to_sql(con=engine, name='table_name', if_exists='replace')

【讨论】:

    【解决方案5】:

    to_sql 方法适合我。

    但是,请记住,它看起来将被弃用以支持 SQLAlchemy:

    FutureWarning: The 'mysql' flavor with DBAPI connection is deprecated and will be removed in future versions. MySQL will be further supported with SQLAlchemy connectables. chunksize=chunksize, dtype=dtype)
    

    【讨论】:

      【解决方案6】:

      您可以将您的 DataFrame 输出为 csv 文件,然后使用 mysqlimport 将您的 csv 导入您的 mysql

      编辑

      似乎pandas's build-in sql util 提供了write_frame 函数,但仅适用于sqlite。

      我发现了一些有用的东西,你可以试试this

      【讨论】:

      • 谢谢,这就是我迄今为止的做法。我正在寻找一种无需 csv 绕道即可直接插入 mysql 的方法。
      【解决方案7】:

      这对我有用。一开始我只创建了数据库,没有创建预定义的表。

      from platform import python_version
      print(python_version())
      3.7.3
      
      path='glass.data'
      df=pd.read_csv(path)
      df.head()
      
      
      !conda install sqlalchemy
      !conda install pymysql
      
      pd.__version__
          '0.24.2'
      
      sqlalchemy.__version__
      '1.3.20'
      

      安装后重启内核。

      from sqlalchemy import create_engine
      engine = create_engine('mysql+pymysql://USER:PASSWORD@HOST:PORT/DATABASE_NAME', echo=False)
      
      try:
      df.to_sql(name='glasstable',con=engine,index=False, if_exists='replace')
      print('Sucessfully written to Database!!!')
      
      except Exception as e:
          print(e)
      

      【讨论】:

        【解决方案8】:

        这应该可以解决问题:

        import pandas as pd
        import pymysql
        pymysql.install_as_MySQLdb()
        from sqlalchemy import create_engine
        
        # Create engine
        engine = create_engine('mysql://USER_NAME_HERE:PASS_HERE@HOST_ADRESS_HERE/DB_NAME_HERE')
        
        # Create the connection and close it(whether successed of failed)
        with engine.begin() as connection:
          df.to_sql(name='INSERT_TABLE_NAME_HERE/INSERT_NEW_TABLE_NAME', con=connection, if_exists='append', index=False)
        

        【讨论】:

          【解决方案9】:

          df.to_sql(name = "owner", con= db_connection, schema = 'aws', if_exists='replace', index = >True, index_label='id')

          【讨论】:

            猜你喜欢
            • 2020-02-13
            • 2018-04-12
            • 1970-01-01
            • 1970-01-01
            • 2020-03-24
            • 2019-01-25
            • 2021-10-27
            • 1970-01-01
            相关资源
            最近更新 更多