Панды, записывающие фрейм данных в другую схему postgresql

10

Я пытаюсь написать pandas DataFrame в базу данных PostgreSQL, используя таблицу, соответствующую критериям схемы.

Я использую следующий код:

import pandas.io.sql as psql
from sqlalchemy import create_engine

engine = create_engine(r'postgresql://some:user@host/db')

c = engine.connect()
conn = c.connection

df = psql.read_sql("SELECT * FROM xxx", con=conn)    
df.to_sql('a_schema.test', engine)

conn.close()

Что происходит, так это то, что pandas записывается в схеме "public", в таблице с именем "a_schema.test", вместо записи в таблицу "test" в схеме "a_schema".

Как я могу указать pandas использовать схему, отличную от общедоступной?

Спасибо

  • 0
    Нет необходимости создавать объект соединения с engine.connect() , вам просто нужно передать движок read_sql . Кроме того, эта функция доступна в pandas верхнего уровня, поэтому нет необходимости импортировать psql для этого.
  • 0
    Да ты прав. Исправлено в моем ответе.
Теги:
pandas
sqlalchemy

2 ответа

14
Лучший ответ

Обновление: начиная с pandas 0,15, поддерживается запись в другую схему. Затем вы сможете использовать аргумент ключевого слова schema:

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

Запись на другую схему пока не поддерживается функциями read_sql и to_sql (но уже был запрошен запрос на повышение: https://github.com/pydata/pandas/issues/7441).

Однако вы можете обойтись теперь, используя интерфейс объекта с помощью PandasSQLAlchemy и предоставляя собственный MetaData объект:

meta = sqlalchemy.MetaData(engine, schema='a_schema')
meta.reflect()
pdsql = pd.io.sql.PandasSQLAlchemy(engine, meta=meta)
pdsql.to_sql(df, 'test')

Осторожно! Этот интерфейс (PandasSQLAlchemy) еще не является общедоступным и будет претерпевать изменения в следующей версии pandas, но вы можете сделать это для pandas 0.14.

Обновление: PandasSQLAlchemy переименовано в SQLDatabase в pandas 0,15.

  • 0
    Это сработало для меня, но я должен был указать kwarg 'схемы' в мета-реализации. Я написал свой ответ соответственно.
1

Решено, благодаря ответу Джориса. Код был также улучшен благодаря комментарию joris, передавая движок sqlalchemy вместо объектов соединения.

import pandas as pd
from sqlalchemy import create_engine, MetaData

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

df = pd.read_sql("SELECT * FROM xxx", con=engine)    
pdsql.to_sql(df, 'test')
  • 0
    Оно живое! Спасибо!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню