Pandas: عند استخدام to_sql () ، هل تريد المتابعة إذا تم اكتشاف مفاتيح أساسية مكررة؟

تم إنشاؤها على ١٣ أبريل ٢٠١٧  ·  19تعليقات  ·  مصدر: pandas-dev/pandas

نموذج التعليمات البرمجية ، مثال يمكن نسخه ولصقه إن أمكن

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

وصف المشكلة

أحاول إلحاق كبير DataFrame بجدول SQL. بعض الصفوف في DataFrame هي نسخ مكررة من تلك الموجودة في جدول SQL ، والبعض الآخر ليس كذلك. لكن to_sql() يتوقف تمامًا عن التنفيذ إذا تم اكتشاف تكرار واحد.

سيكون من المنطقي أن يقوم to_sql(if_exists='append') بمجرد تحذير المستخدم من الصفوف التي بها مفاتيح مكررة والاستمرار في إضافة الصفوف الجديدة ، وعدم التوقف تمامًا عن التنفيذ. بالنسبة لمجموعات البيانات الكبيرة ، من المحتمل أن يكون لديك نسخ مكررة ولكنك تريد تجاهلها.

ربما تضيف حجة لتجاهل التكرارات والاستمرار في التنفيذ؟ ربما خيار إضافي if_exists مثل 'append_skipdupes' ؟

ناتج pd.show_versions()

الإصدارات المثبتة

الالتزام: لا شيء
بيثون: 3.6.0.final.0
بتات الثعبان: 64
نظام التشغيل: Windows
إصدار نظام التشغيل: 10
الجهاز: AMD64
المعالج: Intel64 Family 6 Model 60 Stepping 3، GenuineIntel
byteorder: قليلا
LC_ALL: لا شيء
لانغ: لا شيء
لوكال: English_United States.1252

الباندا: 0.19.2
أنف: لا شيء
النقطة: 9.0.1
أدوات الإعداد: 28.8.0
سايثون: لا شيء
numpy: 1.12.0
scipy: لا شيء
statsmodels: لا شيء
xarray: لا شيء
IPython: 5.3.0
أبو الهول: لا يوجد
باتسي: لا شيء
داتوتيل: ​​2.6.0
بيتز: 2016.10.21
blosc: لا شيء
عنق الزجاجة: لا شيء
الجداول: لا شيء
numexpr: بلا
matplotlib: لا شيء
openpyxl: لا شيء
xlrd: بلا
xlwt: بلا
xlsxwriter: بلا
lxml: لا شيء
bs4: لا شيء
html5lib: 0.999999999
HTplib2: لا شيء
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 Server بإضافة الفهرس مرة أخرى وإسقاط التكرارات.
sqlquery="ALTER IGNORE TABLE 'DATABASE'.'TABLE' ADD UNIQUE INDEX 'idx_name' ('column_name1' ASC, 'column_name2' ASC, 'column_name3' '[ASC | DESC]')"

اعتمادًا على التطبيق المحدد الخاص بك ، يمكن أن يكون هذا مفيدًا.
على أي حال ، فإن الخيار if_exists مثل append_skipdupes سيكون أفضل بكثير.

سيكون 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 .

يعد LOAD DATA أسرع جدًا من 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 باستخدام الوسيطة upsert_ignore ، التي تتناول # 14553.

append_skipdupes +1

+1 من أجل append_skipdupes

توافق على أنه يجب إضافة "append_skipdupes".

نعم من فضلك. يجب إضافة "append_skipdupes" وليس فقط لعمود المفتاح الأساسي. إذا كانت هناك تكرارات بين الأعمدة الفريدة الأخرى ، فيجب أيضًا تخطي إلحاق تلك الصفوف المكررة الجديدة.

+1 من أجل append_skipdupes

append_skipdupes +1

append_skipdupes +1

+1 من أجل append_skipdupes

في غضون ذلك ، يمكنك استخدام هذا https://pypi.org/project/pangres/

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات