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.финал.0
биты питона: 64
ОС: Windows
ОС-выпуск: 10
машина: AMD64
процессор: Intel64 Family 6 Model 60 Stepping 3, GenuineIntel
порядок байтов: маленький
LC_ALL: нет
ЯЗЫК: Нет
МЕСТО: English_United States.1252
панды: 0.19.2
нос: Нет
пункт: 9.0.1
инструменты настройки: 28.8.0
Цитон: нет
номер: 1.12.0
scipy: нет
статистические модели: нет
рентген: нет
IPython: 5.3.0
сфинкс: нет
Пэтси: Нет
датаутилит: 2.6.0
питц: 2016.10
блок: нет
узкое место: нет
столы: нет
числовое выражение: нет
matplotlib: Нет
openpyxl: нет
XLRD: нет
xlwt: нет
xlsxwriter: нет
lxml: нет
бс4: Нет
html5lib: 0.999999999
httplib2: нет
апиклиент: нет
sqlalchemy: 1.1.9
pymysql: нет
psycopg2: нет
Джинджа2: 2.9.5
бото: нет
pandas_datareader: нет
Это также должно поддерживать режим «при дублирующем обновлении».
@rosstripi Я думаю, что идея иметь это, безусловно, будет принята, но, насколько мне известно, основным узким местом является реализация для этого с использованием 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]')"
В зависимости от вашего конкретного приложения это может быть полезно.
В любом случае вариант 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
.
ЗАГРУЗИТЬ ДАННЫЕ намного быстрее, чем ВСТАВИТЬ.
полный код:
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/
Самый полезный комментарий
Это также должно поддерживать режим «при дублирующем обновлении».