Python SQL соединение - Pypyodbc - элемент последовательности 0: ожидаемый экземпляр str, найдены байты - PullRequest
0 голосов
/ 14 сентября 2018

У меня есть функция, которая при передаче базы данных, таблицы и сведений о доступе соединяется с таблицей на SQL-сервере, чтобы прочитать все содержимое для экспорта в кадр данных pandas

def GET_DATA(source_server, source_database, source_table, source_username, source_password):

    print('******* GETTING DATA ' ,source_server, '.', source_database,'.' ,source_table,'.' ,source_username , '*******')
    data_collected = []

    #SOURCE 
    connection = pypyodbc.connect('Driver={ODBC Driver 17 for SQL Server};'
                                'Server=' + source_server + ';'
                                'Database=' + source_database + ' ;'
                                'uid=' + source_username + ';pwd=' + source_password + '')


    #OPEN THE CONNECTION 
    cursor = connection.cursor()

    #BUILD THE COMMAND 
    SQLCommand = ("SELECT * FROM " + source_database +".dbo." + source_table )


    #RUN THE QUERY 
    cursor.execute(SQLCommand)

    #GET RESULTS 
    results = cursor.fetchone()

    columnList = [tuple[0] for tuple in cursor.description]
    #print(type(columnList))

    while results: 

        data_collected.append(results)
        results = cursor.fetchone()

    df_column = pd.DataFrame(columnList)
    df_column = df_column.transpose()
    df_result = pd.DataFrame(data_collected)
    frames = [df_column,df_result]

    df = pd.concat(frames)
    print('GET_DATA COMPLETE!')

    return df

Большую часть времени это работаетхорошо, однако, по причинам, которые я не могу определить, я получаю эту ошибку

sequence item 0: expected str instance, bytes found

Что является причиной этого и как я могу объяснить это?

thx!

Ответы [ 3 ]

0 голосов
/ 12 октября 2018

У меня возникла похожая проблема в одном из моих проектов. Это исключение было вызвано драйвером Microsoft ODBC. По моему мнению, проблема могла возникнуть при получении результатов из БД. Может быть на линии

cursor.fetchone()

Причиной этого исключения, как я уже понял, является размер данных, полученных с SQL Server на Python. Там может быть одна конкретная огромная строка в БД, которая вызывает это. Если строка содержит символы Unicode или символы не ascii, драйвер превышает длину буфера, драйвер не может преобразовать nvarchar в байты и из байтов объект обратно в строку. Когда драйвер встречает некоторые специальные символы, он иногда не может преобразовать объект байтов обратно в строку и, следовательно, в ошибку. Драйвер отправляет объект байтов обратно в python. Я думаю, что это причина для исключения.

Может быть, если вы немного углубитесь в эту конкретную строку данных, которая может вам помочь.

Я также обнаружил еще одну похожую проблему здесь - Нажмите здесь

Может быть, этот URL (известная проблема драйвера Microsoft ODBC) тоже может помочь - Нажмите здесь

0 голосов
/ 05 июля 2019

Я получил ту же ошибку, используя python 3, следующим образом: я определил столбец MS SQL как nchar, сохранил пустую строку (которая в python 3 - это Unicode), а затем получил строку с помощью вызова pypyodbc cursor.fetchone (),Ошибка в этой строке:

if raw_data_parts != []:
     if py_v3:
         if target_type != SQL_C_BINARY:
             raw_value = ''.join(raw_data_parts) 
             # FAILS WITH "sequence item 0: expected str instance, bytes found"
      ....

Изменение типа данных столбца на nvarchar в базе данных исправило его.

0 голосов
/ 14 сентября 2018

Я нашел гораздо лучший способ извлечения данных из SQL в панд

import pyodbc 
import pandas as pd

def GET_DATA_TO_PANDAS(source_server,source_database, source_table,source_username,source_password):
        print('***** STARTING DATA TO PANDAS ********* ')
        con = pyodbc.connect('Driver={ODBC Driver 17 for SQL Server};'
                                    'Server=' + source_server + ';'
                                    'Database=' + source_database + ' ;'
                                    'uid=' + source_username + ';pwd=' + source_password + '')




        #BUILD QUERY 
        query = "SELECT * FROM " + source_database + ".dbo." + source_table
        df = pd.read_sql(query, con)
        return df 

Использовал эту ссылку - https://www.quora.com/How-do-I-get-data-directly-from-databases-DB2-Oracle-MS-SQL-Server-into-Pandas-DataFrames-using-Python

...