Pandas `to_sql` 通过 `if_exists = 'append'` 给出了 `表已存在` 错误

2023-12-07

我正在尝试使用 Pandas (v1.3.4)、SQLAlchemy (v1.4.26) 和 PyMySQL (v1.0.2) 写入 MySQL 数据库。我可以使用 pandas 创建一个新表(称为“test_table”)to_sql方法,但随后尝试写入同一个表会给出:

OperationalError: (pymysql.err.OperationalError) (1050, "Table 'test_table' already exists")

我之前在 SQLite 中完成过此操作,所以我不确定为什么它在 MySQL 中不起作用。这是我的语法问题,还是数据库服务器配置中可能需要更改某些内容?

这是我正在使用的代码。

首先,导入并建立与数据库服务器的连接:

from sqlalchemy import create_engine
import pymysql
import pandas as pd

sqlEngine = create_engine('mysql+pymysql://username:pas[email protected]', pool_recycle=3600)
con  = sqlEngine.connect()

建立具体的数据库名称:

sql = '''
USE my_database
'''
con.execute(sql);

生成一个条目并写入一个名为的新表test_table:

entry = pd.DataFrame({
    'PersonID': 0,
    'LastName': 'smith',
    'FirstName': 'joe',
}, index=[0])
entry.to_sql('test_table', con, if_exists='append')

验证我的条目是否已进入表中:

sql = '''
SELECT *
FROM test_table
'''
pd.read_sql_query(sql, con)

这使:

enter image description here

到目前为止,一切都很好。现在我尝试添加一个新条目test_table表,使用if_exists='append'参数,以便新条目将附加到现有表的末尾:

entry = pd.DataFrame({
    'PersonID': 1,
    'LastName': 'smith',
    'FirstName': 'mary',
}, index=[0])
entry.to_sql('test_table', con, if_exists='append')

结果是:

OperationalError: (pymysql.err.OperationalError) (1050, "Table 'test_table' already exists")
[SQL: 
CREATE TABLE test_table (
    `index` BIGINT, 
    `PersonID` BIGINT, 
    `LastName` TEXT, 
    `FirstName` TEXT
)

]
(Background on this error at: https://sqlalche.me/e/14/e3q8)

为什么 Pandas 试图在这里创建一个新表?我怎样才能强制它附加到现有的表呢?


我遇到了同样的问题,我找到了两种方法来解决它,尽管我不知道为什么会解决它:

  1. 要么在创建连接时在url中传递数据库名称
  2. 或将数据库名称作为模式传递pd.to_sql.

两者都做并没有什么坏处。

```
#create connection to MySQL DB via sqlalchemy & pymysql
user = credentials['user']
password = credentials['password']
port = credentials['port']
host = credentials['hostname']
dialect = 'mysql'
driver = 'pymysql'
db_name = 'test_db'

# setup SQLAlchemy   
from sqlalchemy import create_engine 
cnx = f'{dialect}+{driver}://{user}:{password}@{host}:{port}/' 
engine = create_engine(cnx) 

# create database
with engine.begin() as con:
    con.execute(f"CREATE DATABASE {db_name}")

############################################################
# either pass the db_name  vvvv - HERE- vvvv after creating a database
cnx = f'{dialect}+{driver}://{user}:{password}@{host}:{port}/{db_name}'      
############################################################
engine = create_engine(cnx) 

table = 'test_table'
col = 'test_col'
with engine.begin() as con:
    # this would work here instead of creating a new engine with a new link
    # con.execute(f"USE {db_name}")
    con.execute(f"CREATE TABLE {table} ({col} CHAR(1));")

# insert into database
import pandas as pd
df = pd.DataFrame({col : ['a','b','c']})

with engine.begin() as con:
    # this has no effect here
    # con.execute(f"USE {db_name}")
    df.to_sql(
        name= table,
        if_exists='append',
        con=con, 
############################################################
# or pass it as a schema vvvv - HERE - vvvv
        #schema=db_name,
############################################################
        index=False
    )```

使用python版本测试3.8.13, sqlalchemy1.4.32和熊猫1.4.2。 可能会出现同样的问题here and here.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Pandas `to_sql` 通过 `if_exists = 'append'` 给出了 `表已存在` 错误 的相关文章

随机推荐