Pandas: to_sql()を使用しているときに、重複する主キーが検出された場合は続行しますか?

作成日 2017年04月13日  ·  19コメント  ·  ソース: pandas-dev/pandas

コードサンプル、可能であればコピーして貼り付けることができる例

df.to_sql('TableNameHere', engine, if_exists='append', chunksize=900, index=False)

問題の説明

大きなDataFrameをSQLテーブルに追加しようとしています。 DataFrameの行の一部は、SQLテーブルの行と重複していますが、重複していないものもあります。 ただし、重複が1つでも検出されると、 to_sql()完全に実行を停止します。

to_sql(if_exists='append')は、どの行に重複キーがあるかをユーザーに警告し、実行を完全に停止するのではなく、新しい行を追加し続けることは理にかなっています。 大規模なデータセットの場合、重複する可能性がありますが、無視する必要があります。

重複を無視して実行を続けるための引数を追加するのではないでしょうか。 おそらく、 'append_skipdupes'のような追加のif_existsオプションですか?

pd.show_versions()の出力

インストールされたバージョン

コミット:なし
python:3.6.0.final.0
python-ビット:64
OS:Windows
OSリリース:10
マシン:AMD64
プロセッサ:Intel64ファミリ6モデル60ステッピング3、GenuineIntel
バイトオーダー:少し
LC_ALL:なし
言語:なし
ロケール:English_United States.1252

パンダ:0.19.2
鼻:なし
ピップ:9.0.1
setuptools:28.8.0
Cython:なし
numpy:1.12.0
scipy:なし
statsmodels:なし
xarray:なし
IPython:5.3.0
スフィンクス:なし
patsy:なし
dateutil:2.6.0
pytz:2016.10
blosc:なし
ボトルネック:なし
テーブル:なし
numexpr:なし
matplotlib:なし
openpyxl:なし
xlrd:なし
xlwt:なし
xlsxwriter:なし
lxml:なし
bs4:なし
html5lib:0.999999999
httplib2:なし
apiclient:なし
sqlalchemy:1.1.9
pymysql:なし
psycopg2:なし
jinja2:2.9.5
boto:なし
pandas_datareader:なし

Enhancement IO SQL

最も参考になるコメント

これは、「重複更新時」モードもサポートする必要があります。

全てのコメント19件

これは、「重複更新時」モードもサポートする必要があります。

@rosstripiこれを採用するというアイデアは確かに受け入れられると思いますが、AFAIKの主なボトルネックは、フレーバーにとらわれない方法でsql / sqlalchemyを使用するこの実装です。 これをどのように行うことができるかについてのいくつかの調査は確かに歓迎されています!

こんにちは、これに対する回避策を見つけましたか? 私にお知らせください

この実装に関する更新はありますか?

私は現在、PostgreSQLとSQLAlchemyでこの問題に直面しており、「重複更新時」に問題が発生することを望んでいます。

仕事をありがとう

回避策は、データベース内の一意のインデックスを削除することです。

sqlquery="ALTER 'TABLE DATABASE'.'TABLE' DROP INDEX 'idx_name'"
その後
df.to_sql('TableNameHere', engine, if_exists='append', chunksize=900, index=False)
実行することができます。

MySQLサーバーにインデックスを再度追加させ、重複を削除するだけです。
sqlquery="ALTER IGNORE TABLE 'DATABASE'.'TABLE' ADD UNIQUE INDEX 'idx_name' ('column_name1' ASC, 'column_name2' ASC, 'column_name3' '[ASC | DESC]')"

特定のアプリケーションによっては、これが役立つ場合があります。
とにかく、$# append_skipdupesのような$ if_existsオプションの方がはるかに優れています。

append_skipdupesは、これを処理するのに最適な方法です。

はい、append_skipdupes +1

df.to_sql()のオプションでこれに対処できるとよいことに同意しました。

sqliteで使用する回避策は次のとおりです。

CREATE TABLE IF NOT EXISTS my_table_name (
    some_kind_of_id INT PRIMARY KEY ON CONFLICT IGNORE,
    ...

次に、重複を挿入すると、それらは黙って無視され、非重複は正しく処理されます。 私の場合、データは静的である(つまり、静的である必要がある)ので、更新する必要はありません。 データフィードの形式は、無視できる重複を取得するようなものであるというだけです。

MariaDbとMySqlを使用したその他の回避策:
df.to_csv("test.csv")
次に使用します:
LOAD DATA INFILE 'test.csv' IGNORE INTO TABLE mytableまたは
LOAD DATA INFILE 'test.csv' REPLACE INTO TABLE mytable

LOADDATAはINSERTよりも非常に高速です。

完全なコード:

csv_path = str(Path(application_path) / "tmp" / "tmp.csv").replace("\\", "\\\\")
df.to_csv(csv_path, index=False, sep='\t', quotechar="'", na_rep=r'\N')
rq = """LOAD DATA LOCAL INFILE '{file_path}' REPLACE INTO TABLE {db}.{db_table}
        LINES TERMINATED BY '\\r\\n'
        IGNORE 1 LINES
         ({col});
        """.format(db=db,
                   file_path=csv_path,
                   db_table=table_name,
                   col=",".join(df.columns.tolist()))

これは#29636で、#14553に対応するupsert_ignore引数で対処されていると思います。

append_skipdupes +1

append_skipdupesの場合は+1

同意する 'append_skipdupes'を追加する必要があります。

はい、お願いします。 主キー列だけでなく、「append_skipdupes」を追加する必要があります。 他の一意の列の間に重複がある場合も、それらの新しい重複行の追加をスキップする必要があります。

append_skipdupesの場合は+1

append_skipdupes +1

append_skipdupes +1

append_skipdupesの場合は+1

その間、このhttps://pypi.org/project/pangres/を使用できます

このページは役に立ちましたか?
0 / 5 - 0 評価