Ошибка индекса индекса вне диапазона при обработке поля длинной строки SQL - PullRequest
0 голосов
/ 07 января 2020

Короче говоря - я создал эмулятор терминала в Python, предназначенный для взаимодействия с базой данных MS SQL. Я только что реализовал механизм преобразования SQL - XML, который позволяет пользователю экспортировать выбранную таблицу в предварительно отформатированный файл XML, однако, когда я пытаюсь обработать данные из AdventureWorks2012-> HumanResources.Department таблица, содержащая очень длинные строки, я получаю ошибку List index out of range - это не относится к более мелким, более гуманным полям в пользовательской базе данных.

Ссылка на репо: https://github.com/jsarnowski96/pysql-console

Как это работает с небольшими пользовательскими таблицами:

enter image description here

Как это работает с AdventureWorks2012 база данных: enter image description here enter image description here

Содержимое HumanResources.Department Таблица: enter image description here

Предполагаемый фрагмент кода:

with open(finalPath, "w+", newline='') as xmlFile:
            xmlFile.write("<?xml version='1.0' ?>\n")
            xmlFile.write("<%s>\n" % table)
            for row in rows:
                 xmlFile.write("\t<field>\n")
                 indent_count += 1
                 for j in range(len(row)):
                     xmlFile.write("\t" * indent_count + "<%s>\n" % str(columns[j]))
                     xmlFile.write("\t" * (indent_count + 1) + "%s\n" % str(row[j]))
                     xmlFile.write("\t" * indent_count)
                     xmlFile.write("</%s>\n" % str(columns[j]))
                 indent_count = 1
                 xmlFile.write("\t</field>\n")
            xmlFile.write("</%s>\n" % table)
            print("SQL-XML conversion task finished successfully. File",fileName,"has been created.\n")

РЕДАКТИРОВАТЬ: после переноса всего в верхний слой для l oop с итератором columns ошибка исчезает, однако не сохраняет ни одной строки в файл назначения:

enter image description here

Модифицированная часть:

for i in range(len(columns)):
     for row in rows:
          xmlFile.write("\t<field>\n")
          indent_count += 1
          iterator = i
          for j in range(len(row)):
               xmlFile.write("\t" * indent_count + "<%s>\n" % str(columns[iterator]))
               xmlFile.write("\t" * (indent_count + 1) + "%s\n" % str(row[j]))
               xmlFile.write("\t" * indent_count)
               xmlFile.write("</%s>\n" % str(columns[iterator]))
               iterator += 1
          indent_count = 1
          xmlFile.write("\t</field>\n")

Кому Мне кажется, что в приведенном выше случае программа даже не выполняет второй for l oop, поэтому в файле нет тега <field>.

1 Ответ

1 голос
/ 16 января 2020

Глядя на ваш код в GitHub, я думаю, что проблема может заключаться в том, что вы на самом деле неправильно заполняете массив columns, оставляя его пустым. Это объясняет ошибки, выходящие за пределы допустимого диапазона.

Я загрузил базу данных AdventureWorks2012 на свой собственный сервер SQL и запустил исходный файл columnsQuery SQL из вашего кода:

select column_name
from information_schema.columns
where table_name = 'HumanResources.Department'

и это не дало результатов для имен столбцов:

enter image description here

Однако изменение запроса дало правильные результаты имени столбца:

enter image description here

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

import pyodbc

dbConnection  = pyodbc.connect('Driver={SQL Server};'
                      'Server=CPMLT5YHJMQ2;'
                      'Database=AdventureWorks2012;'
                      'Trusted_Connection=yes;')

table = 'HumanResources.Department';

columnsQuery = list("SELECT name FROM sys.columns WHERE OBJECT_ID = OBJECT_ID('" + table + "')")
columnsQuery = ''.join(columnsQuery)

cursor = dbConnection .cursor()
cols = cursor.execute(columnsQuery).fetchall()
columns = list(str(c) for c in cols)
columns = list([c.replace('(','').replace(')','').replace(' ','').replace("'",'').replace(',','').strip() for c in columns])

selectQuery = list("select * from " + table)
selectQuery = ''.join(selectQuery)
rows = cursor.execute(selectQuery).fetchall()

with open("test.xml", "w+", newline='') as xmlFile:
    xmlFile.write("<?xml version='1.0' ?>\n")
    xmlFile.write("<%s>\n" % table)
    indent_count = 1
    for row in rows:
        xmlFile.write("\t<field>\n")
        indent_count += 1
        for j in range(len(row)):
            xmlFile.write("\t" * indent_count + "<%s>\n" % str(columns[j]))
            xmlFile.write("\t" * (indent_count + 1) + "%s\n" % str(row[j]))
            xmlFile.write("\t" * indent_count)
            xmlFile.write("</%s>\n" % str(columns[j]))
        xmlFile.write("\t</field>\n")
        indent_count = 1
    xmlFile.write("</%s>\n" % table)
    xmlFile.close()

Это создает файл xml, подобный :

enter image description here

Надеюсь, это даст вам возможность поработать.

...