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

2da*_*aaa 1 python sql postgresql sqlalchemy pandas

我正在尝试将数据框的内容写入除"公共"模式之外的模式中的表.我按照Pandas中描述的模式将数据帧写入其他postgresql模式:

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)
Run Code Online (Sandbox Code Playgroud)

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

pdsql.to_sql(df, 'table', if_exists='append')
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

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.
Run Code Online (Sandbox Code Playgroud)

我也尝试添加extend_existing=Truereflect通话中,但这似乎没有什么区别.

如何让pandas写入此表?

jor*_*ris 9

更新:从pandas 0.15开始,支持写入不同的模式.然后您就可以使用schema关键字参数:

df.to_sql('test', engine, schema='a_schema')
Run Code Online (Sandbox Code Playgroud)

正如我在链接问题中所说的那样,目前还不支持使用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
Run Code Online (Sandbox Code Playgroud)

然后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')
Run Code Online (Sandbox Code Playgroud)

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

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

更新:在pandas 0.15中PandasSQLAlchemy重命名为SQLDatabase.