Python 通过数据帧循环并在附加到数据库之前检查行

Python 通过数据帧循环并在附加到数据库之前检查行,python,pandas,sqlite,dataframe,finance,Python,Pandas,Sqlite,Dataframe,Finance,问题如何将数据框附加到数据库中,以便它检查是否存在股票代码,而只附加不存在股票代码的行 这就是我所做的过程 将CSV文件导入数据帧 指定与数据库中相同的列名 使用下面的代码将数据帧发送到数据库,但是 sqlite3.IntegrityError:唯一约束失败:stocks.stock\u ticker conn = sqlite3.connect('stockmarket.db') c = conn.cursor() df.to_sql(name='stocks', con=conn, if_

问题如何将数据框附加到数据库中,以便它检查是否存在股票代码,而只附加不存在股票代码的行

这就是我所做的过程

  • 将CSV文件导入数据帧
  • 指定与数据库中相同的列名
  • 使用下面的代码将数据帧发送到数据库,但是
  • sqlite3.IntegrityError:唯一约束失败:stocks.stock\u ticker

    conn = sqlite3.connect('stockmarket.db')
    c = conn.cursor()
    
    df.to_sql(name='stocks', con=conn, if_exists='append', index=False)
    
    conn.commit()
    
    我查看了其他完整性错误案例,但似乎找不到一个适用于附加数据帧的案例?我发现并尝试了这个,但它所做的只是没有附加任何东西

    try:
        conn = sqlite3.connect('stockmarket.db')
        c = conn.cursor()
        df.to_sql(name='stocks', con=conn, if_exists='append', index=False)
        conn.commit()
    except sqlite3.IntegrityError:
        print("Already in database")
    
    
    我不确定我是否正确理解了迭代

    所以我尝试了这个,但它只是在数据库中打印出了它们中的每一个。甚至还有4家新股票上市公司

    for index, row in df.iterrows():
        try:
            conn = sqlite3.connect('stockmarket.db')
            c = conn.cursor()
            df.to_sql(name='stocks', con=conn, if_exists='append', index=False)
            conn.commit()
        except sqlite3.IntegrityError:
            print("Already in database")
    
    

    数据库如下所示


    任何值得赞赏的见解:)

    发生这种情况的原因是,如果您试图将数据附加到具有相同(唯一)主键或违反某些其他唯一性约束的表中,Pandas不允许对冲突策略声明正确的
    <代码>如果_存在
    仅指整个表本身,而不是每一行

    我想你已经想出了一个很好的答案,也许稍加修改就可以了:

    # After connecting
    for i in range(len(df)):
        try:
            df[df.index == i].to_sql(name='stocks', con=conn, if_exists='append', index=False)
            conn.commit()
        except sqlite3.IntegrityError:
            pass
    
    现在,如果您希望在Pandas数据中出现较新的值,并且假设您希望替换数据库中的旧值,那么这可能是一个问题。在这种情况下,您可能希望使用原始SQL命令作为字符串,并以迭代方式传递值。例如:

    insert_statement = """
    INSERT INTO stocks (stock_id,
                        stock_ticker,
                        {other columns})
    VALUES (%s, %s, {as many %s as columns})
    ON CONFLICT (stock_id) DO UPDATE
        SET {Define which values you will update on conflict}"""
    
    然后你就可以跑了

    for i in range(len(df)):
        values = tuple(df.iloc[i])
        cursor.execute(insert_statement, values)
    

    感谢您抽出时间来帮助我:)。我尝试了第一个代码,我对原始问题进行了编辑,以显示它的外观以及我得到的错误。我加对了吗?关于你建议的第二部分。我设置了所有列名,但是我要将%s更改为什么?也不知道我是怎么改变集合中的点的。。。也抱歉,在第42天/100天学习编码挑战中出现了noobie问题>df.iloc[i],Pandas似乎不知道如何将此系列发送到数据库(因此
    表stocks没有名为0的列)。我在第一个街区换了那条线。关于第二个,具体的语法实际上取决于数据库。例如,在Postgres中,语法是这样工作的:最后,
    %s
    只是字符串格式的符号,请参见此处:非常感谢您的帮助!您的编辑解决了我的问题:),现在请尝试通过链接了解如何完成您添加的第二部分。直到你指出来我才意识到。也就是说,我需要能够用新信息更新股票代码行,不添加新的股票代码行(如果它们已经存在的话)>。