【问题标题】:create new columns in existing sql table, with extra columns from pandas Dataframe在现有 sql 表中创建新列,并使用 pandas Dataframe 中的额外列
【发布时间】:2016-11-27 16:28:54
【问题描述】:

我有几个pandas Dataframe 想写入SQL database。但是,因为现有的 SQL database 可能没有 pandas Dataframe 中的特定 column name,所以我收到一条错误消息,指出 the column in the table was not found, thus unable to append data

# Example:

df1 
out= column1, column2, column3, column4
     value1,  value2,  value3,  value4

df2
out= columnA, columnB, columnC
     valueA,  valueB,  valueC

# Initially I concat the df together and save it into SQL
combined_data = pandas.concat([df1, df2], axis=1,
                               join='inner')
pandas.DataFrame.to_sql(combined_data, name='table1', con=engine, 
                        if_exists='append', index=False)

但是,由于已经创建了包含所有列的表,如果 df2 要包含其他列,我会收到一条错误消息。

df2
out= columnA, columnB, columnC, columnD, columnE, columnF
     valueA,  valueB,  valueC,  valueD,  valueE,  valueF      

我如何构造一个代码,它将在现有 SQL table 中创建新列,这些列的名称与 pandas Dataframe 中缺少的列名称一样?

我想我可以用下面的sql code添加新列

connection.execute("ALTER TABLE table1 ADD COLUMN new_column INTEGER DEFAULT 0")

但是如何确保添加的 new_column 跟在 df2 中的列名之后?

【问题讨论】:

    标签: python sqlite sqlalchemy


    【解决方案1】:

    我也遇到了类似的问题,采取了以下方法:

    1) 从数据库表中获取列的列表。这可以通过多种方式完成,但我使用的是 postgres 而不是 sqllite。请参阅this SE 问题以从 postgresql 获取表的列名。 This question 似乎回答了如何为 sqlite 做。

    db_columns = list(engine.execute("SELECT column_name FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'my_table'")) 
    

    这会返回一个元组列表,因此获取每个元组的第一个:

    db_columns = [x[0] for x in db_columns]
    

    您可以将表格加载到 pandas 中,然后改用数据框的列。这显然会占用更多资源:

    db_columns = pd.read_sql_query("SELECT * FROM my_table", connection).columns
    

    2) 获取数据库表的列和df的列之间的差异。我喜欢使用集合,因为我发现它们很直观。但是他们不保持秩序:

    new_columns = set(df1.columns) - set(db_columns)

    如果顺序很重要,那么您可以使用过滤器:

    new_columns = list(filter(lambda x: x not in db_columns, df1.columns))

    3) 遍历新列并准备将它们添加到表中:

    query = ''   
    query params = []
    for column in new_columns:
    query+= "ALTER TABLE %s ADD COLUMN %s %s;"  
    query_params.extend(["my_table", column,"text"])
    

    在此示例中,我使用了“文本”,但您可能希望将其替换为对应于 pandas/numpy dtype 的原始数据类型。 np.asscalar(value) 是将 numpy 类型转换为 python 类型的一种方法。有关将 numpy 转换为 python 类型的更多信息,请参阅this SO question。 最后将所有列添加到表中:

     result = connection.execute(query, query_params)
    

    【讨论】:

    • 我收到此错误:(1064,“您的 SQL 语法有错误;请查看与您的 MySQL 服务器版本相对应的手册,以获取在 ''my_table' ADD 附近使用的正确语法第 1 行的 COLUMN 'col2' 'text''")
    • 听起来您有语法错误。我建议仔细重新阅读您的代码并确保您具有有效的语法(注意语法可能因不同的 SQL 变体而异......我使用 Postgresql 是为了它的价值),如果您仍然无法编写自己的问题。从您评论中的有限信息来看,很难提供任何额外的见解。
    猜你喜欢
    • 2021-12-22
    • 1970-01-01
    • 2015-03-09
    • 2017-03-27
    • 2016-02-10
    • 1970-01-01
    • 1970-01-01
    • 2022-06-14
    • 2019-02-17
    相关资源
    最近更新 更多