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,)]