重复主键上的Pandas to_sql失败

时间:2015-05-19 22:41:59

标签: python mysql pandas

我想使用pandas df.to_sql()函数附加到现有表。

我设置if_exists='append',但我的表有主键。

在尝试insert ignore到现有表时,我想做相当于append的操作,因此我会避免重复输入错误。

这是否可以使用pandas,还是需要编写显式查询?

6 个答案:

答案 0 :(得分:10)

遗憾的是,没有指定“INSERT IGNORE”的选项。这就是我如何解决这个限制,将行插入到那个不重复的数据库中(数据帧名称为df)

for i in range(len(df)):
    try:
        df.iloc[i:i+1].to_sql(name="Table_Name",if_exists='append',con = Engine)
    except IntegrityError:
        pass #or any other action

答案 1 :(得分:1)

请注意"if_exists='append'"与表的现有相关,以及不存在时该怎么办。 if_exists不与表的内容相关。 请参阅此处的文档:https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_sql.html

  

if_exists:{'fail','replace','append'},默认'失败'   失败:如果表存在,则不执行任何操作。   replace:如果表存在,则删除它,重新创建它,然后插入数据。   append:如果表存在,则插入数据。如果不存在则创建。

答案 2 :(得分:0)

Pandas不支持编辑.to_sql方法的实际SQL语法,因此您可能会失败。有一些实验性的程序化变通方法(比如,使用CALCHIPAN将SQL框架读取到SQLAlchemy对象并使用SQLAlchemy进行事务处理),但是通过将DataFrame写入CSV并使用显式MySQL函数加载它可能会更好。

CALCHIPAN回购:https://bitbucket.org/zzzeek/calchipan/

答案 3 :(得分:0)

我在仍然遇到IntegrityError的地方遇到了麻烦 enter image description here

...很奇怪,但是我只是采用了上面的方法,然后将其倒退了:

<cfset apiSecret = 'j6hriaKY2iZi+Y2uo9JJldmO1Bq79XB8d1v2uHzAK0Zvy972mIs8ThsJSQeDlZJz+HzmLD6Q1MUZb5X1Zf9MzQ=='>
<cfset stringToSign = 'POST#chr(10)#x-csod-api-key:1lie8ficql9h5#chr(10)#x-csod-date:2015-09-08T11:27:32.000#chr(10)#/services/api/sts/session'>

<cfset secretKey = toBinary(apiSecret)>
<cfset signature = toBase64(
    binaryDecode(
        hmac(stringToSign, secretKey, 'HMACSHA512'),
        'HEX'
    )
)>

<cfoutput>#signature#</cfoutput>

答案 4 :(得分:0)

在我的情况下,我试图在一个空表中插入新数据,但是有些行是重复的,在这里几乎是同一问题,我“可能”考虑获取现有数据并与我得到的新数据合并并继续进行,但这并不是最佳选择,可能只适用于小数据,而不适用于大表。

由于大熊猫目前无法为这种情况提供任何处理方式,因此我一直在寻找合适的解决方法,因此我做出了自己的决定,不确定是否对您有用,但我决定控制我的数据是第一位的,而不是等待是否成功的好运,所以我所做的是在致电.to_sql之前删除了重复项,因此,如果发生任何错误,我将对我的数据有更多了解,并确保知道发生了什么情况:

import pandas as pd


def write_to_table(table_name, data):
    df = pd.DataFrame(data)
    # Sort by price, so we remove the duplicates after keeping the lowest only
    data.sort(key=lambda row: row['price'])
    df.drop_duplicates(subset=['id_key'], keep='first', inplace=True)
    #
    df.to_sql(table_name, engine, index=False, if_exists='append', schema='public')

因此,在我的情况下,我想保持最低的行价格(顺便说一句,我正在将dict的{​​{1}}数组传递给data),为此,我确实进行了排序,这不是必需的,但是这是我要控制要保留的数据的示例。

我希望这会对与我的情况差不多的人有所帮助。

答案 5 :(得分:0)

Pandas目前没有其他选择,但这是the Github issue。如果您也需要此功能,只需对其进行投票。