pandas.DataFrame.to_sql
- DataFrame.to_sql(name, con, *, schema=None, if_exists='fail', index=True, index_label=None, chunksize=None, dtype=None, method=None)[source]
-
Запись записей, хранящихся в DataFrame, в базу данных SQL.
Поддерживаются базы данных, поддерживаемые SQLAlchemy [1]. Таблицы могут быть созданы, добавлены или перезаписаны.
- Параметры:
-
- name:str
-
Имя SQL таблицы.
- con:sqlalchemy.engine.(Engine or Connection) or sqlite3.Connection
-
Использование SQLAlchemy позволяет использовать любую базу данных, поддерживаемую этой библиотекой. Обеспечивается обратная совместимость с объектами sqlite3.Connection. Пользователь отвечает за удаление движка и закрытие соединения для соединяемого объекта SQLAlchemy. См. здесь. Если передается sqlalchemy.engine.Connection, которая уже находится в транзакции, транзакция не будет подтверждена. Если передается sqlite3.Connection, отменить вставку записей не получится.
- schema:str, необязательно
-
Укажите схему (если это поддерживается типом базы данных). Если None, используется схема по умолчанию.
- if_exists:{‘fail’, ‘replace’, ‘append’}, по умолчанию ‘fail’
-
Как себя вести, если таблица уже существует.
fail: Вызвать ValueError.
replace: Удалить таблицу перед вставкой новых значений.
append: Добавить новые значения в существующую таблицу.
- index:bool, по умолчанию True
-
Записать индекс DataFrame как столбец. Использует index_label в качестве имени столбца в таблице. Создает индекс таблицы для этого столбца.
- index_label:str или последовательность, по умолчанию None
-
Метка столбца для столбца(ов) индекса. Если задано None (по умолчанию) и index равно True, используются имена индекса. Последовательность должна быть задана, если DataFrame использует MultiIndex.
- chunksize:int, необязательно
-
Укажите количество строк в каждом блоке для записи за раз. По умолчанию все строки записываются сразу.
- dtype:словарь или скаляр, необязательно
-
Указание типа данных для столбцов. Если используется словарь, ключи должны быть именами столбцов, а значения — типами SQLAlchemy или строками для режима совместимости sqlite3. Если указан скаляр, он будет применен ко всем столбцам.
- method:{None, ‘multi’, callable}, необязательно
-
Управляет используемой SQL-операторной частью вставки:
None : Использует стандартную SQL
INSERT(по одной строке).‘multi’: Передает несколько значений в одном
INSERT.callable с сигнатурой
(pd_table, conn, keys, data_iter).
Подробности и пример реализации вызова см. в разделе insert method.
- Возвращает:
-
- None или int
-
Количество строк, затронутых to_sql. Возвращает None, если вызов callable, переданный в
method, не возвращает целое число строк.Возвращаемое количество затронутых строк — сумма атрибута
rowcountsqlite3.Cursorили соединяемого объекта SQLAlchemy, которое может не отражать точное количество записанных строк, как указано в 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')]Также можно передать 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для определения callable метода вставки, который ничего не делает, если есть конфликт первичного ключа в таблице 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, callable для обновления столбцов
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
Укажите dtype (особенно полезно для целых чисел с пропущенными значениями). Обратите внимание, что хотя 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,)]
© 2008–2022, AQR Capital Management, LLC, Lambda Foundry, Inc. and PyData Development Team
Licensed under the 3-clause BSD License.
https://pandas.pydata.org/pandas-docs/version/2.2.2/reference/api/pandas.DataFrame.to_sql.html