Pandas: Saat menggunakan to_sql(), lanjutkan jika kunci utama duplikat terdeteksi?

Dibuat pada 13 Apr 2017  ·  19Komentar  ·  Sumber: pandas-dev/pandas

Contoh Kode, contoh yang dapat disalin jika memungkinkan

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

Deskripsi masalah

Saya mencoba menambahkan DataFrame besar ke tabel SQL. Beberapa baris di DataFrame adalah duplikat dari yang ada di tabel SQL, beberapa tidak. Tapi to_sql() benar-benar berhenti mengeksekusi jika bahkan satu duplikat terdeteksi.

Masuk akal jika to_sql(if_exists='append') hanya memperingatkan pengguna baris mana yang memiliki kunci duplikat dan terus menambahkan baris baru, tidak sepenuhnya berhenti mengeksekusi. Untuk kumpulan data besar, Anda mungkin akan memiliki duplikat tetapi ingin mengabaikannya.

Mungkin menambahkan argumen untuk mengabaikan duplikat dan terus mengeksekusi? Mungkin opsi if_exists tambahan seperti 'append_skipdupes' ?

Keluaran pd.show_versions()

VERSI TERINSTAL

komit: Tidak ada
python: 3.6.0.final.0
python-bit: 64
OS: Windows
Rilis OS: 10
mesin: AMD64
prosesor: Intel64 Family 6 Model 60 Stepping 3, GenuineIntel
urutan byte: sedikit
LC_ALL: Tidak ada
LANG: Tidak ada
LOCALE: English_United States.1252

panda: 0.19.2
hidung: Tidak ada
pip: 9.0.1
alat penyiapan: 28.8.0
Cython: Tidak ada
numpy: 1.12.0
scipy: Tidak ada
statsmodels: Tidak ada
xarray: Tidak ada
IPython: 5.3.0
sphinx: Tidak ada
patty: Tidak ada
dateutil: 2.6.0
pytz: 2016.10
blok: Tidak ada
kemacetan: Tidak ada
tabel: Tidak ada
numexpr: Tidak ada
matplotlib: Tidak ada
openpyxl: Tidak ada
xlrd: Tidak ada
xlwt: Tidak ada
xlsxpenulis: Tidak ada
lxml: Tidak ada
bs4: Tidak ada
html5lib: 0,999999999
httplib2: Tidak ada
apiklien: Tidak ada
sqlalchemy: 1.1.9
pymysql: Tidak ada
psycopg2: Tidak ada
jinja2: 2.9.5
boto: Tidak ada
pandas_datareader: Tidak ada

Enhancement IO SQL

Komentar yang paling membantu

Ini juga harus mendukung mode "pada pembaruan duplikat".

Semua 19 komentar

Ini juga harus mendukung mode "pada pembaruan duplikat".

@rosstripi Saya pikir ide untuk memiliki ini pasti akan diterima, tetapi AFAIK hambatan utama adalah implementasi untuk ini menggunakan sql/sqlalchemy dengan cara agnostik rasa. Beberapa eksplorasi bagaimana ini bisa dilakukan tentu disambut baik!

Hai, apakah Anda menemukan solusi untuk ini? Tolong beritahu saya

Adakah pembaruan tentang implementasi ini?

Saya sekarang menghadapi masalah ini dengan PostgreSQL dan SQLAlchemy dan ingin memiliki "pada pembaruan duplikat".

Terima kasih atas kerja samanya

Solusinya adalah menghapus indeks unik dalam database:

sqlquery="ALTER 'TABLE DATABASE'.'TABLE' DROP INDEX 'idx_name'"
setelah itu
df.to_sql('TableNameHere', engine, if_exists='append', chunksize=900, index=False)
dapat dieksekusi.

Biarkan Server MySQL Anda menambahkan indeks lagi dan jatuhkan duplikatnya.
sqlquery="ALTER IGNORE TABLE 'DATABASE'.'TABLE' ADD UNIQUE INDEX 'idx_name' ('column_name1' ASC, 'column_name2' ASC, 'column_name3' '[ASC | DESC]')"

Tergantung pada aplikasi spesifik Anda, ini dapat membantu.
Pokoknya opsi if_exists seperti append_skipdupes akan jauh lebih baik.

append_skipdupes akan menjadi cara sempurna untuk menangani ini.

ya, append_skipdupes +1

Setuju bahwa akan baik untuk dapat menangani ini dengan opsi di df.to_sql() .

Inilah solusi yang saya gunakan di sqlite:

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

Kemudian, ketika saya memasukkan duplikat, mereka diabaikan secara diam-diam, dan non-duplikat diproses dengan benar. Dalam kasus saya, datanya (yaitu seharusnya ) statis, jadi saya tidak perlu memperbarui. Hanya saja bentuk data feed-nya sedemikian rupa sehingga saya akan mendapatkan duplikat yang diabaikan.

solusi lain dengan MariaDb dan MySql :
df.to_csv("test.csv")
kemudian gunakan:
LOAD DATA INFILE 'test.csv' IGNORE INTO TABLE mytable atau
LOAD DATA INFILE 'test.csv' REPLACE INTO TABLE mytable .

LOAD DATA lebih cepat dari INSERT.

kode lengkap:

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()))

Saya yakin ini sedang ditangani di #29636 dengan argumen upsert_ignore , yang membahas #14553.

append_skipdupes +1

+1 untuk append_skipdupes

Setuju 'append_skipdupes' harus ditambahkan.

Ya silahkan. 'append_skipdupes' harus ditambahkan dan tidak hanya untuk kolom Kunci Utama. Jika ada duplikat di antara kolom Unik lainnya, itu juga harus melewati penambahan baris duplikat baru itu.

+1 untuk append_skipdupes

append_skipdupes +1

append_skipdupes +1

+1 untuk append_skipdupes

Sementara itu Anda dapat menggunakan ini https://pypi.org/project/pangres/

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

mpenning picture mpenning  ·  48Komentar

rvernica picture rvernica  ·  46Komentar

jsexauer picture jsexauer  ·  81Komentar

datapythonista picture datapythonista  ·  44Komentar

jreback picture jreback  ·  61Komentar