在PostgreSQL上,Pandas to_sql除了'public'之外不能写入架构

时间:2014-08-07 03:59:58

标签: python sql postgresql pandas sqlalchemy

我试图将数据框的内容写入模式中的表格,除了公共'架构。我遵循Pandas writing dataframe to other postgresql schema中描述的模式:

meta = sqlalchemy.MetaData()
engine = create_engine('postgresql://some:user@host/db')
meta = sqlalchemy.MetaData(engine, schema='schema')
meta.reflect(engine, schema='schema')
pdsql = pandas.io.sql.PandasSQLAlchemy(engine, meta=meta)

但是当我试着写到桌子上时:

pdsql.to_sql(df, 'table', if_exists='append')

我收到以下错误:

InvalidRequestError: Table 'schema.table' is already defined for this MetaData instance.  Specify 'extend_existing=True' to redefine options and columns on an existing Table object.

我还尝试在extend_existing=True电话中添加reflect,但这似乎没有什么区别。

如何让pandas写入此表?

1 个答案:

答案 0 :(得分:7)

更新:从pandas 0.15开始,支持写入不同的架构。然后,您将能够使用schema关键字参数:

df.to_sql('test', engine, schema='a_schema')

正如我在链接question中所述,目前尚未支持使用read_sqlto_sql函数来写入不同的架构(但已提交增强请求: https://github.com/pydata/pandas/issues/7441)。

但是,我描述了使用对象接口的解决方法。但我在那里描述的只适用于添加表一次,而不是用于替换和/或附加表。因此,如果您只想添加,请先删除现有表,然后再次写入。

如果你想附加到表中,下面是一个更多的hacky解决方法。首先重新定义has_tableget_table

def has_table(self, name):
    return self.engine.has_table(name, schema=self.meta.schema)

def get_table(self, table_name):
    if self.meta.schema:
        table_name = self.meta.schema + '.' + table_name
    return self.meta.tables.get(table_name)

pd.io.sql.PandasSQLAlchemy.has_table = has_table
pd.io.sql.PandasSQLAlchemy.get_table = get_table

然后像你一样创建PandasSQLAlchemy对象,并写下数据:

meta = sqlalchemy.MetaData(engine, schema='schema')
meta.reflect()
pdsql = pd.io.sql.PandasSQLAlchemy(engine, meta=meta)
pdsql.to_sql(df, 'table', if_exists='append')

这显然不是一个好方法,但我们正努力为0.15提供更好的API。如果您想提供帮助,请参阅https://github.com/pydata/pandas/issues/7441

小心!这个界面(PandasSQLAlchemy)还没有真正公开,并且在下一版本的pandas中仍然会有变化,但这就是你如何为pandas 0.14(.1)做的。

更新:在{pandas 0.15}中将PandasSQLAlchemy重命名为SQLDatabase