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)[源代码]#
将存储在 DataFrame 中的记录写入 SQL 数据库。
SQLAlchemy 支持的数据库 [1] 都支持。表可以新建、追加或覆盖。
- 参数:
- 名字str
SQL 表的名称。
- conADBC 连接, sqlalchemy.engine.(Engine 或 Connection) 或 sqlite3.Connection
ADBC 提供了高性能的 I/O 和原生类型支持(如果可用)。使用 SQLAlchemy 可以使其支持该库支持的任何数据库。对于 sqlite3.Connection 对象提供了遗留支持。用户负责处理 SQLAlchemy 可连接对象的引擎处置和连接关闭。请参见 这里。如果传递一个已经在事务中的 sqlalchemy.engine.Connection,事务将不会被提交。如果传递一个 sqlite3.Connection,将无法回滚记录插入。
- schemastr, 可选
指定模式(如果数据库类型支持此功能)。如果为 None,则使用默认模式。
- 如果存在{‘fail’, ‘replace’, ‘append’}, 默认 ‘fail’
如果表已经存在,如何表现。
fail: 引发一个 ValueError。
replace: 在插入新值之前删除表。
append: 将新值插入现有表中。
- 索引布尔值, 默认为 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)
的可调用对象。
详细信息和一个示例的可调用实现可以在 插入方法 部分找到。
- 返回:
- 无或整数
通过 to_sql 影响的行数。如果传递给
method
的可调用对象没有返回一个整数行数,则返回 None。返回的行数受
sqlite3.Cursor
或 SQLAlchemy 可连接对象的rowcount
属性的影响,这可能不会反映写入行的确切数量,如 sqlite3 或 SQLAlchemy 中所述。Added in version 1.4.0.
- 引发:
- ValueError
当表已经存在且 if_exists 为 ‘fail’(默认值)时。
参见
read_sql
从表中读取一个 DataFrame。
备注
如果数据库支持,时区感知的日期时间列将使用 SQLAlchemy 写为
带时区的Timestamp
类型。否则,日期时间将存储为原始时区本地的无时区时间戳。并非所有数据存储都支持
method="multi"
。例如,Oracle 不支持多值插入。参考文献
[1]请提供需要翻译的具体内容。
例子
创建一个内存中的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
定义一个可调用的插入方法,如果在 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", # noqa: F821 ... method=insert_on_conflict_nothing) 0
对于MySQL,一个在主键冲突时更新列
b
和c
的可调用对象。>>> from sqlalchemy.dialects.mysql import insert # noqa: F811 >>> 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", # noqa: F821 ... 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,)]
Added in version 2.2.0: pandas 现在通过 ADBC 驱动程序支持写入
>>> df = pd.DataFrame({'name' : ['User 10', 'User 11', 'User 12']}) >>> df name 0 User 10 1 User 11 2 User 12
>>> from adbc_driver_sqlite import dbapi >>> with dbapi.connect("sqlite://") as conn: ... df.to_sql(name="users", con=conn) 3