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:なし
これは、「重複更新時」モードもサポートする必要があります。
@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/を使用できます
最も参考になるコメント
これは、「重複更新時」モードもサポートする必要があります。