Создание резервной копии базы данных ms sql server через pyodbc

ordosgreen

Новичок
Пользователь
Май 7, 2020
2
0
1
Поясните пожалуйста логику работы курсора.

Есть курсор к встроенной бд. там все понятно, кинули Select, получили поля, одно из них есть json с параметрами, распарсили. Второй курсор, тот который в коде зовется "mscursor" поднимается уже с целевым сервером, на котором лежат базы и с них надо снять копии. Я с курсорами работал только в рамках DML (select, update, insert), а тут по коду нужно выполнить команду на сбор резервной копии. код отрабатывает корректно, но мне не понятен следующий кусок:
while mscursor.nextset():
pass
этот кусок я подсмотрел на stackoverflow, без него не происходит создание файла резервной копии, точнее файл создается, но тут же удаляется, т.к. транзакция завершается rollback'ом на стороне сервера, проверял sql profiler'ом. Очевидно, что скрипт доходя до команды execute(resultstring), отправляет ее серверу, не дожидаясь окончания выполнения переходит к следующему значению в results, и отправляет команду на выполнение уже для другой базы. по завершению закрывает соединение. т.к. на целевом сервере базы большие, резервные копии делаются несколько минут, а не секунду. и скуль просто не успевает обработать запрос до закрытия соединения после чего происходит автоматический откат. Собственно вопросы, почему mscursor.execute(resultstring) не дожидается окончания выполнения запроса, второй почему происходит откат транзакции хотя стоит cnxn.autocommit = True и третий что делает этот код
while mscursor.nextset():
pass

версия python 3.8
версия сервера бд ms sql server 2008 r2
версия ОС под которой запускается скрипт win 10 pro

полный код скрипта ниже:
Python:
import sqlite3
import json
import datetime
import pyodbc

conn = sqlite3.connect("store.db")
cursor = conn.cursor()
sql = "SELECT * FROM databases"

server = 'someserver'
database = 'master'
username = 'login'
password = 'password'
cnxn = pyodbc.connect(
    'DRIVER={ODBC Driver 17 for SQL Server};SERVER=' + server + ';DATABASE=' + database + ';UID=' + username + ';PWD=' + password)
cnxn.autocommit = True;
mscursor = cnxn.cursor()
cursor.execute(sql)
results = cursor.fetchall()
for i in results:
    params = json.loads(i[4])
    datetimestr = datetime.datetime.strftime(datetime.datetime.now(), "%Y_%m_%d_%H_%M_%S")
    params['fullpath'] = params['backuppath'] + params['databasename'] + '_' + datetimestr + '.bak'
    resultstring = i[3].format(name=i[1], path=params['fullpath'])
    print(resultstring)
    mscursor.execute(resultstring)
    while mscursor.nextset():
        pass
cnxn.close()
Заранее спасибо, прошу сильно не пинать.
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
cursor.nextset() возвращает следующий набор данных если он есть. В итоге while работает пока есть данные.
Вот тут можно почитать про методы курсора: https://code.google.com/archive/p/pyodbc/wikis/Cursor.wiki
 

ordosgreen

Новичок
Пользователь
Май 7, 2020
2
0
1
cursor.nextset() возвращает следующий набор данных если он есть. В итоге while работает пока есть данные.
Вот тут можно почитать про методы курсора: https://code.google.com/archive/p/pyodbc/wikis/Cursor.wiki
Спасибо за отклик, я похожее описание видел. Я просто не вкурил, какие могут возвращаться данные при выполнении инструкции backup data base, более того во множественном числе, и что их перебор заканчивается только по окончании выполнения бэкапа. Просто, мало ли, мб кто сталкивался с подобным. В отладке я ничего не увидел.
UPD. а как вообще можно посмотреть на набор который сейчас в курсоре? fetchall() так же как и fetchone() возвращает только ошибку, что "{ProgrammingError}No results. Previous SQL was not a query."
 

Форум IT Специалистов