python pandas:仅将数据帧的结构(无行)导出到 SQL

Posted

技术标签:

【中文标题】python pandas:仅将数据帧的结构(无行)导出到 SQL【英文标题】:python pandas: export structure only (no rows) of a dataframe to SQL 【发布时间】:2015-06-27 06:22:03 【问题描述】:

我正在使用 pandas 0.16 和 sqlalchemy。 是否可以仅将数据帧的结构(即列名和数据类型,但不包括行)导出到 SQL?

我设法做到的最接近的是仅导出第一行:

df.ix[[0],:].to_sql( tablename, myconnection )

然后我必须做一个截断表。但是,to_csv 和 to_sql 方法之间存在不一致:to_csv 将布尔字段写入字符串 'TRUE' 或 'FALSE' ,而 to_sql 将它们写入 0 或 1。这意味着导入文件使用 dataframe.to_csv 创建更复杂比它应该的。

如果我跑步

df.ix[[],:].to_sql( tablename, myconnection )

这不起作用,因为所有列都导出为文本。

【问题讨论】:

【参考方案1】:

.to_sql() 支持 dict= 参数,可让您将列类型指定为 SQLAlchemy 类型。

df.ix[[], :].to_sql(tablename, myconnection, dtype=
    'column1': sqlalchemy.types.Float,
    'column2': sqlalchemy.types.BigInt,
    'column3': sqlalchemy.types.Date,
)

... 将允许您将列映射到它们各自的SQLAlchemy types。

【讨论】:

所以,回顾一下,如果我传输至少一行,pandas/sqlalchemy 会创建正确的数据类型,否则它们会将所有列创建为文本。解决这个问题的唯一方法是手动且痛苦地指定每列的数据类型,这正是我想要避免的。 Pandas 半生不熟的 SQL 支持一秒就越来越令人沮丧! 是的,恐怕这里的问题出在this line。 data.ix[[0], :].iloc[:, 0].dtype 返回正确的 dtype,但 data.ix[[], :].iloc[:, 0].dtype 没有。可能值得提出一个问题。【参考方案2】:

你可以使用get_schema函数:

from pandas.io.sql import get_schema

engine = ...
df = ..
get_schema(df, 'table_name', con=engine)

这将为您提供否则将以字符串形式创建的架构,您可以使用 engine.execute 执行该架构

此外,to_sql 将布尔数据写入 0 和 1 的原因是,SQL Server 没有布尔数据类型(参见例如Is there a Boolean data type in Microsoft SQL Server like there is in mysql?)

【讨论】:

谢谢。 get_schema 是否记录在任何地方?我在pandas.pydata.org/pandas-docs/version/0.16.0/…中找不到它 你是对的,这不在 API 文档中。我为此开了一个问题:github.com/pydata/pandas/issues/9960 但是,你能用这个解决你的问题吗?还是还没有?另一种可能性是创建一个io.sql.SQLTable 对象并获取它的table 属性,它提供了一个SQLAlchemy Table,您可以使用create() 创建它 如果我想覆盖 pandas 和 SQL alchemy 的默认数据类型映射,我似乎可以将字典传递给 dtype。这很有用。还有一个问题:我可以控制 Python 在表上创建的约束吗?例如。对于布尔列,它添加了值必须为 0 或 1 的约束)。我可以运行 SQL 语句来删除或禁用约束,但我希望首先选择创建没有约束的表【参考方案3】:

也许你可以尝试 drop 方法来删​​除所有行。

import pandas as pd
from sqlalchemy import create_engine

df = pd.read_csv("c:\\Users\\ym\\Desktop\\out.csv")
# just drop all rows
df = df.drop(df.index[ [x for x in range(0,len(df))]])
engine = create_engine('mysql://root:root@127.0.0.1:3306/test?charset=utf8', echo=False)
df.to_sql(name=table_name, con=engine, if_exists='replace', chunksize=1000 ,index=False)

【讨论】:

以上是关于python pandas:仅将数据帧的结构(无行)导出到 SQL的主要内容,如果未能解决你的问题,请参考以下文章

Python/Pandas 仅将字符串转换为时间

用于附加和创建pandas数据帧的快速numpy数组结构

python 减少Pandas数据帧的内存使用量。

Python_Executing 来自 Pandas 数据帧的所有值的特定行

python 在Jupyter Notebook中设置pandas数据帧的宽度

Python Pandas:如何在数据帧的每行中选择两个相等的列