如何通过mysqldb将熊猫数据框插入数据库?
Posted
技术标签:
【中文标题】如何通过mysqldb将熊猫数据框插入数据库?【英文标题】:How to insert pandas dataframe via mysqldb into database? 【发布时间】:2013-05-04 19:01:54 【问题描述】:我可以从 python 连接到我的本地 mysql 数据库,我可以创建、选择和插入单独的行。
我的问题是:我可以直接指示 mysqldb 获取整个数据帧并将其插入现有表中,还是需要遍历行?
在任何一种情况下,对于具有 ID 和两个数据列以及匹配数据框的非常简单的表,python 脚本会是什么样子?
【问题讨论】:
您需要使用 mysqldb,还是可以使用其他 MySQL 连接器? 【参考方案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_frame
的flavor
设置为'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。
【讨论】:
Andy - 关于如何处理 pandas 0.20.2 弃用 'mysql' 风格的任何想法? @pshep123 使用 SQLAlchemy:***.com/a/30653988/1240268***.com/a/29356874/1240268pandas.pydata.org/pandas-docs/stable/…(引擎而不是连接) 太好了,不知道为什么我没有从搜索中发现这一点,但确实成功了,谢谢! 不推荐使用这种方法 (sql.write_frame) - ***.com/questions/38487878/… 什么是默认架构?来自 pandas 文档:“schemastr,可选指定架构(如果数据库风格支持此)。如果没有,则使用默认架构。”【参考方案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')
类似的线程:
-
Writing to MySQL database with pandas using SQLAlchemy, to_sql
Writing a Pandas Dataframe to MySQL
【讨论】:
name
参数应该是表名,而不是数据库名。
to_sql 的风味 kwarg 不再被允许。
谢谢! index=False
帮我解决了以下错误:(mysql.connector.errors.ProgrammingError) 1170 (42000): BLOB/TEXT column "index" used in key specification without a key length
【参考方案4】:
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)
【讨论】:
【参考方案5】: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')
【讨论】:
【参考方案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')
【讨论】:
以上是关于如何通过mysqldb将熊猫数据框插入数据库?的主要内容,如果未能解决你的问题,请参考以下文章
通过某些(索引)参数将值插入熊猫数据框中“适当”位置的最佳方法是啥?