【问题标题】:python pandas: export structure only (no rows) of a dataframe to SQLpython pandas:仅将数据帧的结构(无行)导出到 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 )

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

【问题讨论】:

    标签: python pandas sqlalchemy


    【解决方案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 linedata.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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-26
      • 1970-01-01
      • 1970-01-01
      • 2012-07-04
      • 1970-01-01
      • 2017-04-15
      • 2015-08-03
      相关资源
      最近更新 更多