Python - Postgres запрос с использованием sqlalchemy возвращает «Пустой кадр данных» - PullRequest
0 голосов
/ 18 февраля 2020

Я пытаюсь запросить некоторые данные из базы данных postgres и добавить результаты в Excel с помощью приведенного ниже кода Python (я подключаюсь к серверу через туннель s sh и подключаюсь к базе данных с помощью sqlalchemy):

from sshtunnel import SSHTunnelForwarder
from sqlalchemy.orm import sessionmaker 
from sqlalchemy import create_engine
import pandas as pd
from pandas import DataFrame
import xlsxwriter
import openpyxl

with SSHTunnelForwarder(
    ('<server_ip>', 22),
    ssh_username="<server_username>",
    ssh_private_key='<private_key_path>', 
    remote_bind_address=('localhost', 5432)) as server:
    server.start()
    print "server connected"

    #connect to DB
    local_port = str(server.local_bind_port)
    engine = create_engine('postgresql://<db_username>:<db_password>:' + local_port +'/<db_name>')
    Session = sessionmaker(bind=engine)
    s = Session()
    print 'Database session created'

    not_empty_query = False #flag empty queries
    arg_query = "SELECT * from portalpage where id not in (select entityid from sharepermissions where entitytype='PortalPage')"
    query = s.execute(arg_query)
    print(query)
    for row in query: #check if the query is empty
        if (row[0] > 0):
            not_empty_query = True
            break
    if not_empty_query == True: #if the query isn not empty add response into excel
        df = pd.DataFrame(pd.np.empty((0, 8)))
        df = DataFrame(query.fetchall())
        print(df)
        df.columns = query.keys()
        df.to_excel("out.xlsx", engine="openpyxl", sheet_name="Worksheet_Name")

s.close()

Он работает для большинства запросов, которые я пытался выполнить, однако с помощью вышеприведенного запроса он возвращает следующую ошибку:

ValueError: Length mismatch: Expected axis has 0 elements, new values have 8 elements

Во время устранения неполадок я распечатал параметр df, и я получил «Пустой кадр данных». Однако, когда я выполняю тот же запрос в своей базе данных напрямую, я получаю результаты.

Я также заметил, что в ответе в моей базе данных некоторые столбцы пусты (не уверен, что это имеет значение).

Пожалуйста, также найдите экран печати кода выполнения. enter image description here

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

for row in query: #check if the query is empty
    if (row[0] > 0):
        not_empty_query = True
        break
if not_empty_query == True:

Однако, если я уберу это 'для l oop' затем для других запросов (в основном для запросов, которые возвращают пустые результаты) я получаю ту же ошибку. Пожалуйста, найдите пример ниже. enter image description here

Есть идеи?

Ответы [ 2 ]

1 голос
/ 26 февраля 2020

Пожалуйста, попробуйте это. Я обнаружил, что проблема заключается в том, что logi c, который вы используете, чтобы проверить, возвращает ли запрос какие-либо данные, является проблемой. Я изменил его, чтобы сначала проверить. Если есть какая-либо возвращаемая строка, то она строит фрейм данных и затем экспортирует в Excel. Пожалуйста, дайте мне знать, если это работает.

from sshtunnel import SSHTunnelForwarder
from sqlalchemy.orm import sessionmaker 
from sqlalchemy import create_engine
import pandas as pd
from pandas import DataFrame
import xlsxwriter
import openpyxl

with SSHTunnelForwarder(
    ('<server_ip>', 22),
    ssh_username="<server_username>",
    ssh_private_key='<private_key_path>', 
    remote_bind_address=('localhost', 5432)) as server:
    server.start()
    print "server connected"

    #connect to DB
    local_port = str(server.local_bind_port)
    engine = create_engine('postgresql://<db_username>:<db_password>:' + local_port +'/<db_name>')
    Session = sessionmaker(bind=engine)
    s = Session()
    print 'Database session created'
    arg_query = "SELECT * from portalpage where id not in (select entityid from sharepermissions where entitytype='PortalPage')"
    query = conn.execute(arg_query)##rows_count
    rows = query.fetchall()
    columns=query.keys()
    if len(rows) > 0:
        df = DataFrame(rows)
        df.columns =columns
        df.to_excel("out.xlsx", engine="openpyxl", sheet_name="Worksheet_Name")
    else:
        print "no data"
0 голосов
/ 18 февраля 2020

Попробуйте сначала создать пустой фрейм данных.

if not_empty_query == True: #if the query isn not empty add response into excel
        df = pd.DataFrame(pd.np.empty((0, 8)))   
        df = DataFrame(query.fetchall())
        print(df)
        df.columns = query.keys()
        df.to_excel("out.xlsx", engine="openpyxl", sheet_name="Worksheet_Name")
...