pandas.DataFrame.to_sql#
- DataFrame.to_sql(имя, con, *, схема=None, if_exists='fail', index=True, index_label=None, chunksize=None, dtype=None, метод=None)[источник]#
Записать записи, хранящиеся в DataFrame, в базу данных SQL.
Базы данных, поддерживаемые SQLAlchemy [1] поддерживаются. Таблицы могут быть созданы заново, дополнены или перезаписаны.
- Параметры:
- имяstr
Имя таблицы SQL.
- consqlalchemy.engine.(Engine или Connection) или sqlite3.Connection
Использование SQLAlchemy позволяет использовать любую БД, поддерживаемую этой библиотекой. Предоставляется устаревшая поддержка для объектов sqlite3.Connection. Пользователь отвечает за удаление движка и закрытие соединения для подключаемого объекта SQLAlchemy. См. здесь. Если передается sqlalchemy.engine.Connection, который уже находится в транзакции, транзакция не будет зафиксирована. Если передается sqlite3.Connection, не будет возможности откатить вставку записи.
- схемаstr, optional
Укажите схему (если СУБД поддерживает это). Если None, используется схема по умолчанию.
- if_exists{‘fail’, ‘replace’, ‘append’}, по умолчанию ‘fail’
Как вести себя, если таблица уже существует.
fail: Вызывает ValueError.
replace: Удалить таблицу перед вставкой новых значений.
append: Добавить новые значения в существующую таблицу.
- indexbool, по умолчанию True
Запись индекса DataFrame как столбца. Использует index_label в качестве имени столбца в таблице. Создаёт табличный индекс для этого столбца.
- index_labelstr или последовательность, по умолчанию None
Метка столбца для индексных столбцов. Если указано None (по умолчанию) и index имеет значение True, тогда используются имена индекса. Последовательность должна быть указана, если DataFrame использует MultiIndex.
- chunksizeint, необязательный
Укажите количество строк в каждой партии для записи за раз. По умолчанию все строки будут записаны сразу.
- dtypeсловарь или скаляр, необязательно
Указание типа данных для столбцов. Если используется словарь, ключи должны быть именами столбцов, а значения — типами SQLAlchemy или строками для устаревшего режима sqlite3. Если предоставлено скалярное значение, оно будет применено ко всем столбцам.
- метод{None, ‘multi’, callable}, опционально
Управляет SQL-предложением вставки:
None : Использует стандартный SQL
INSERTусловие (по одному на строку).'multi': Передать несколько значений в одном
INSERTпредложение.вызываемый объект с сигнатурой
(pd_table, conn, keys, data_iter).
Подробности и пример реализации вызываемого объекта можно найти в разделе метод insert.
- Возвращает:
- None или int
Количество строк, затронутых to_sql. None возвращается, если вызываемый объект передан в
methodне возвращает целое число строк.Количество возвращённых затронутых строк — это сумма
rowcountатрибутsqlite3.Cursorили SQLAlchemy connectable, которые могут не отражать точное количество записанных строк, как указано в sqlite3 или SQLAlchemy.Добавлено в версии 1.4.0.
- Вызывает:
- ValueError
Когда таблица уже существует и if_exists равен 'fail' (по умолчанию).
Смотрите также
read_sqlЧтение DataFrame из таблицы.
Примечания
Столбцы datetime с учетом часового пояса будут записаны как
Timestamp with timezoneтип с SQLAlchemy, если поддерживается базой данных. В противном случае даты-время будут храниться как временные метки без учета часового пояса, локальные для исходного часового пояса.Не все хранилища данных поддерживают
method="multi". Oracle, например, не поддерживает вставку нескольких значений.Ссылки
Примеры
Создайте базу данных SQLite в памяти.
>>> from sqlalchemy import create_engine >>> engine = create_engine('sqlite://', echo=False)
Создать таблицу с нуля с 3 строками.
>>> df = pd.DataFrame({'name' : ['User 1', 'User 2', 'User 3']}) >>> df name 0 User 1 1 User 2 2 User 3
>>> df.to_sql(name='users', con=engine) 3 >>> from sqlalchemy import text >>> with engine.connect() as conn: ... conn.execute(text("SELECT * FROM users")).fetchall() [(0, 'User 1'), (1, 'User 2'), (2, 'User 3')]
An sqlalchemy.engine.Connection также может быть передано в con:
>>> with engine.begin() as connection: ... df1 = pd.DataFrame({'name' : ['User 4', 'User 5']}) ... df1.to_sql(name='users', con=connection, if_exists='append') 2
Это разрешено для поддержки операций, требующих использования одного и того же соединения DBAPI для всей операции.
>>> df2 = pd.DataFrame({'name' : ['User 6', 'User 7']}) >>> df2.to_sql(name='users', con=engine, if_exists='append') 2 >>> with engine.connect() as conn: ... conn.execute(text("SELECT * FROM users")).fetchall() [(0, 'User 1'), (1, 'User 2'), (2, 'User 3'), (0, 'User 4'), (1, 'User 5'), (0, 'User 6'), (1, 'User 7')]
Перезаписать таблицу только
df2.>>> df2.to_sql(name='users', con=engine, if_exists='replace', ... index_label='id') 2 >>> with engine.connect() as conn: ... conn.execute(text("SELECT * FROM users")).fetchall() [(0, 'User 6'), (1, 'User 7')]
Используйте
methodчтобы определить вызываемый метод вставки, который ничего не делает, если возникает конфликт первичного ключа в таблице базы данных PostgreSQL.>>> from sqlalchemy.dialects.postgresql import insert >>> def insert_on_conflict_nothing(table, conn, keys, data_iter): ... # "a" is the primary key in "conflict_table" ... data = [dict(zip(keys, row)) for row in data_iter] ... stmt = insert(table.table).values(data).on_conflict_do_nothing(index_elements=["a"]) ... result = conn.execute(stmt) ... return result.rowcount >>> df_conflict.to_sql(name="conflict_table", con=conn, if_exists="append", method=insert_on_conflict_nothing) 0
Для MySQL, вызываемый объект для обновления столбцов
bиcесли есть конфликт по первичному ключу.>>> from sqlalchemy.dialects.mysql import insert >>> def insert_on_conflict_update(table, conn, keys, data_iter): ... # update columns "b" and "c" on primary key conflict ... data = [dict(zip(keys, row)) for row in data_iter] ... stmt = ( ... insert(table.table) ... .values(data) ... ) ... stmt = stmt.on_duplicate_key_update(b=stmt.inserted.b, c=stmt.inserted.c) ... result = conn.execute(stmt) ... return result.rowcount >>> df_conflict.to_sql(name="conflict_table", con=conn, if_exists="append", method=insert_on_conflict_update) 2
Укажите тип данных (особенно полезно для целых чисел с пропущенными значениями). Обратите внимание, что хотя pandas вынужден хранить данные как числа с плавающей точкой, база данных поддерживает нулевые целые числа. При получении данных с помощью Python мы получаем целочисленные скаляры.
>>> df = pd.DataFrame({"A": [1, None, 2]}) >>> df A 0 1.0 1 NaN 2 2.0
>>> from sqlalchemy.types import Integer >>> df.to_sql(name='integers', con=engine, index=False, ... dtype={"A": Integer()}) 3
>>> with engine.connect() as conn: ... conn.execute(text("SELECT * FROM integers")).fetchall() [(1,), (None,), (2,)]