Вернуть Pandas dataframe из запроса PostgreSQL с помощью sqlalchemy

23

Я хочу запросить базу данных PostgreSQL и вернуть результат в виде фрейма Pandas.

Я использую sqlalchemy для создания соединения с базой данных:

from sqlalchemy import create_engine
engine = create_engine('postgresql://user@localhost:5432/mydb')

Я пишу DataFrame Pandas в таблицу базы данных:

i=pd.read_csv(path)
i.to_sql('Stat_Table',engine,if_exists='replace')

Основываясь на docs, выглядит так: pd.read_sql_query() должен принять механизм SQLAlchemy:

a=pd.read_sql_query('select * from Stat_Table',con=engine)

Но это вызывает ошибку:

ProgrammingError: (ProgrammingError) relation "stat_table" does not exist

Я использую Pandas версию 0.14.1.

Каков правильный способ сделать это?

Теги:
pandas
sqlalchemy

2 ответа

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

Вас укушают проблемы с чувствительностью к случаю (в) с PostgreSQL. Если вы укажете имя таблицы в запросе, она будет работать:

df = pd.read_sql_query('select * from "Stat_Table"',con=engine)

Но лично я бы посоветовал всегда использовать имена таблиц нижних регистров (и имена столбцов), а также при написании таблицы в базе данных для предотвращения таких проблем.


В документах PostgreSQL (http://www.postgresql.org/docs/8.0/static/sql-syntax.html#SQL-SYNTAX-IDENTIFIERS):

Вычисление идентификатора также делает его чувствительным к регистру, тогда как неупомянутые имена всегда складываются в нижний регистр

Чтобы объяснить немного больше: вы создали таблицу с именем Stat_Table в базу данных (и sqlalchemy укажет это имя, поэтому оно будет записано как "Stat_Table" в базе данных postgres). При выполнении запроса 'select * from Stat_Table' имя без кавычек будет преобразовано в нижний регистр Stat_Table, и вы получите сообщение о том, что эта таблица не найдена.

См. например, также Являются ли имена столбцов PostgreSQL чувствительными к регистру?

2

Сообщение об ошибке сообщает вам, что таблица с именем:

stat_table

не существует (отношение является таблицей в postgres). Поэтому, конечно, вы не можете выбирать из него строки. Проверьте свой db после выполнения:

i.to_sql('Stat_Table',engine,if_exists='replace')

и посмотреть, была ли создана таблица с этим именем в вашем db.

Когда я использую ваше выражение для чтения:

df = pd.read_sql_query('select * from Stat_Table',con=engine)

Я получаю данные обратно из db postgres, поэтому нет ничего плохого в этом.

  • 1
    Благодарю. Проверено и таблица действительно создана. Как сказал @joris, это была проблема с чувствительностью к регистру в имени таблицы: я переписал таблицу: i.to_sql('stat_table',engine,if_exists='replace') и затем он работает: a=pd.read_sql_query('select * from stat_table',engine)
  • 0
    @Imart999 Imart999, когда я писал: посмотрите, была ли создана таблица с таким именем в вашей базе данных - это имя ссылается на имя в сообщении об ошибке, которое было stat_table . Имя сообщения об ошибке является тем, что имеет отношение - с ЛЮБОЙ ошибкой вы получаете. И поскольку python НИКОГДА не делает ошибку, ошибка означала, что ваш код НИКОГДА не создал таблицу с именем stat_name . Посмотрите, как я разместил имя таблицы stat_name в ее собственном абзаце и выделил его - это должно было привлечь ваше внимание к нему.
Показать ещё 2 комментария

Ещё вопросы

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