Con commit python что это
Рассмотрим основные операции с базой данных SQLite с помощью библиотеки sqlite3 на примере таблицы:
CREATE TABLE people ( id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, age INTEGER )
Добавление данных
Для добавления данных применяется SQL-инструкция INSERT . Для добавления одной строки используем метод execute() объекта Cursor:
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() # добавляем строку в таблицу people cursor.execute("INSERT INTO people (name, age) VALUES ('Tom', 38)") # выполняем транзакцию con.commit()
Здесь добавляется одна строка, где name = «Tom», а age = 38.
Выражение INSERT неявно открывает транзакцию, для завершения которой необходимо вызвать метод commit() текущего объекта Connection.
Установка параметров
С помощью второго параметра в метод execute() можно передать значения для параметров SQL-запроса:
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() # данные для добавления bob = ("Bob", 42) cursor.execute("INSERT INTO people (name, age) VALUES (?, ?)", bob) con.commit()
В данном случае добавляемые в БД значения представляют кортеж bob. В SQL-запросе вместо конкретных значений используются знаки подстановки ?. Вместо этих символов при выполнении запроса будут вставляться данные из кортежа data. Так, первый элемент кортежа — строка «Bob» передается на место первого знакак ?, второй элемент — число 42 передается на место второго знака ?.
И если мы посмотрим на содержимое базы данных, то найдем там все добавленные объекты:

Множественная вставка
Метод executemany() позволяет вставить набор строк:
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() # данные для добавления people = [("Sam", 28), ("Alice", 33), ("Kate", 25)] cursor.executemany("INSERT INTO people (name, age) VALUES (?, ?)", people) con.commit()
В метод cursor.executemany() по сути передается то же самое выражение SQL, только теперь данные определены в виде списка кортежей people. Фактически каждый кортеж в этом списке представляет отдельную строку — данные отдельного пользователя, и при выполнении метода для каждого кортежа будет создаваться свое выражение INSERT INTO

Получение данных
Для получения данных применяется SQL-команда SELECT . После выполнения этой команды курсор получает данные, которые можно получить с помощью одного из методов: fetchall() (возвращает список со всеми строками), fetchmany() (возвращает указанное количество строк) и fetchone() (возвращает одну в наборе строку).
Получение всех строк
Например, получим все ранее добавленные данные из таблицы people:
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() # получаем все данные из таблицы people cursor.execute("SELECT * FROM people") print(cursor.fetchall())
При выполнении этой программы на консоль будет выведен список строк, где каждая строка представляет кортеж:
[(1, 'Tom', 38), (2, 'Bob', 42), (3, 'Sam', 28), (4, 'Alice', 33), (5, 'Kate', 25)]
При необходимости мы можем перебрать список, используя стандартные циклические конструкции:
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() cursor.execute("SELECT * FROM people") for person in cursor.fetchall(): print(f" - ")
Результат работы программы:
Tom - 38 Bob - 42 Sam - 28 Alice - 33 Kate - 25
Стоит отметить, что в примере выше необязательно вызывать метод fetchall, мы можем перебрать курсор в цикле как обычный набор:
for person in cursor: print(f" - ")
Получение части строк
Получение части строк с помощью метода fetchmany() , в который передается количество строк:
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() cursor.execute("SELECT * FROM people") # извлекаем первые 3 строки в полученном наборе print(cursor.fetchmany(3))
Результат работы программы:
[(1, 'Tom', 38), (2, 'Bob', 42), (3, 'Sam', 28)]
Выполнение этого метода извлекает следующие ранее неизвлеченные строки:
# извлекаем первые 3 строки в полученном наборе print(cursor.fetchmany(3)) # [(1, 'Tom', 38), (2, 'Bob', 42), (3, 'Sam', 28)] # извлекаем следующие 3 строки в полученном наборе print(cursor.fetchmany(3)) # [(4, 'Alice', 33), (5, 'Kate', 25)]
Получение одной строки
Метод fetchone() извлекает следующую строку в виде кортежа значений и возвращает его. Если строк больше нет, то возвращает None :
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() cursor.execute("SELECT * FROM people") # извлекаем одну строку print(cursor.fetchone()) # (1, 'Tom', 38)
Данный метод удобно применять, когда нам надо извлечь из базы данных только один объект:
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() cursor.execute("SELECT name, age FROM people WHERE раскладываем кортеж на две переменных name, age = cursor.fetchone() print(f"Name: Age: ") # Name: Bob Age: 42
Здесь получаем из бд строку с и полученный результат раскладываем на две переменных name и age (так как кортеж в Python можно разложить на отдельные значения)
Обновление
Для обновления в SQL выполняется команда UPDATE . Например, заменим у всех пользователей имя с Tom на Tomas:
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() # обновляем строки, где name = Tom cursor.execute("UPDATE people SET name ='Tomas' WHERE name='Tom'") # вариант с подстановками # cursor.execute("UPDATE people SET name =? WHERE name=?", ("Tomas", "Tom")) con.commit() # проверяем cursor.execute("SELECT * FROM people") print(cursor.fetchall()) # [(1, 'Tomas', 38), (2, 'Bob', 42), (3, 'Sam', 28), (4, 'Alice', 33), (5, 'Kate', 25)]
Для выполнения обновления также надо выполнять метод con.commit()
Удаление данных
Для удаления в SQL выполняется команда DЕLETE . Например, удалим всех пользователей с именем Bob:
import sqlite3; con = sqlite3.connect("metanit.db") cursor = con.cursor() # обновляем строки, где name = Tom cursor.execute("DELETE FROM people WHERE name=?", ("Bob",)) con.commit() # проверяем cursor.execute("SELECT * FROM people") print(cursor.fetchall()) # [(1, 'Tomas', 38), (3, 'Sam', 28), (4, 'Alice', 33), (5, 'Kate', 25)]
Для выполнения удаления также надо выполнять метод con.commit()
Методы execute, executemany, executescript, commit, rollback
На предыдущих занятиях мы с вами рассмотрели основы языка SQL для взаимодействия с СУБД SQLite. Теперь поговорим о методах пакета sqlite3, то есть, об API данной СУБД. Некоторые моменты мы уже затрагивали и отмечали, что для базовой работы с БД можно использовать менеджер контекста:
import sqlite3 as sq with sq.connect("cars.db") as con: cur = con.cursor() cur.execute("""CREATE TABLE IF NOT EXISTS cars ( car_id INTEGER PRIMARY KEY AUTOINCREMENT, model TEXT, price INTEGER )""")
- con.commit() – применение всех изменений в таблицах БД;
- con.close() – закрытие соединения с БД.
Методы execute, executemany и executescript
Давайте добавим в таблицу cars несколько записей. В самом простом случае это можно сделать так:
cur.execute("INSERT INTO cars VALUES(1,'Audi',52642)") cur.execute("INSERT INTO cars VALUES(2,'Mercedes',57127)") cur.execute("INSERT INTO cars VALUES(3,'Skoda',9000)") cur.execute("INSERT INTO cars VALUES(4,'Volvo',29000)") cur.execute("INSERT INTO cars VALUES(5,'Bentley',350000)")

В результате, таблица будет содержать данные: Однако, когда мы программируем на Python, то данные, как правило, хранятся в каких-либо коллекциях, например, так:
cars = [ ('Audi', 52642), ('Mercedes', 57127), ('Skoda', 9000), ('Volvo', 29000), ('Bentley', 350000) ]
И мы бы хотели брать значения из этого списка и передавать их в SQL-запрос. Для этого запрос следует записывать в виде следующего шаблона:
cur.execute("INSERT INTO cars VALUES(NULL, ?, ?)", cars[0])
Здесь вместо знаков вопроса будут подставлены соответствующие данные из первого кортежа списка. Соответственно, весь набор ранее приведенных строчек, можно заменить циклом:
for car in cars: cur.execute("INSERT INTO cars VALUES(NULL, ?, ?)", car)
Или, еще проще, воспользоваться методом executemany, который специально для этого и существует:
cur.executemany("INSERT INTO cars VALUES(NULL, ?, ?)", cars)
Сразу же здесь отмечу, что помимо знаков вопроса можно использовать именованные параметры (плейсхолдеры). Для этого в запросе перед ними ставится двоеточие, а затем, указывается словарь, где имя – это ключ, вместо которого будет подставлено его значение:
cur.execute("UPDATE cars SET price = :Price WHERE model LIKE 'A%'", {'Price': 0})
Далее, если нужно выполнить несколько отдельных SQL-команд, то можно передать их СУБД с помощью метода executescript:
cur.executescript("""DELETE FROM cars WHERE model LIKE 'A%'; UPDATE cars SET price = price+1000 """)
Мы здесь сначала удаляем все записи, у которых модель начинается на букву A, а затем у оставшихся записей увеличиваем цену на 1000. Причем, команды должны отделяться друг от друга точкой с запятой. У этого метода есть одно ограничение: здесь нельзя использовать шаблоны запросов, как мы это делали в предыдущих методах. В executescript буквально записываются SQL-запросы как есть со всеми данными.
Методы commit и rollback
Давайте теперь реализуем соединение с БД через блок обработки исключений try/except/finally:
con = None try: con = sq.connect("cars.db") cur = con.cursor() cur.executescript("""CREATE TABLE IF NOT EXISTS cars ( car_id INTEGER PRIMARY KEY AUTOINCREMENT, model TEXT, price INTEGER ); BEGIN; INSERT INTO cars VALUES(NULL,'Audi',52642); INSERT INTO cars VALUES(NULL,'Mercedes',57127); INSERT INTO cars VALUES(NULL,'Skoda',9000); INSERT INTO cars VALUES(NULL,'Volvo',29000); INSERT INTO cars VALUES(NULL,'Bentley',350000); UPDATE cars SET price = price+1000 """) con.commit() except sq.Error as e: if con: con.rollback() print("Ошибка выполнения запроса") finally: if con: con.close()
В чем преимущество такого подхода? Смотрите, мы здесь сами «вручную» вызываем методы commit и close. Если операции с таблицами прошли успешно, то они будут сохранены, если же возникли какие-либо ошибки (исключения), то будет вызван метод rollback, который откатывает состояние БД в состояние отметки BEGIN, то есть, все внесенные изменения применены не будут. Например, укажем в команде UDPATE неверное имя таблицы:
UPDATE cars2 SET price = price+1000
При запуске программы произойдет ошибка выполнения запроса и состояние БД не изменится, то есть, все новые добавленные записи не появятся в таблице cars. А вот если вместо rollback указать commit, то увидим добавление записей. То есть, при использовании менеджера контекста в данном случае не выполнилась бы только последняя команда, но отката состояния БД не произошло бы. Вот так более тонко можно управлять состоянием таблиц в БД. Если при работе с БД предполагается сохранять вносимые изменения сразу после выполнения SQL-запроса, то это можно сделать с помощью метода connect, установив в нем параметр isolation_level=None:
with sq.connect("cars.db", isolation_level=None) as con: cur = con.cursor() cur.executescript("""INSERT INTO cars VALUES(NULL,'Audi',52642); INSERT INTO cars VALUES(NULL,'Mercedes',57127); INSERT INTO cars VALUES(NULL,'Skoda',9000); INSERT INTO cars VALUES(NULL,'Volvo',29000); INSERT INTO cars VALUES(NULL,'Bentley',350000); """)
Однако так делать без особой надобности не стоит, т.к. это уменьшает скорость работы с БД из-за постоянной записи данных непосредственно в файл. Без изменения этого параметра все изменения сохраняются в памяти, а потому работа происходит куда быстрее.
Свойство lastrowid

Давайте теперь представим, что у нас есть еще одна таблица cust, которая содержит покупателей машин. Причем, если происходит покупка по «trade-in», то прежняя машина владельца добавляется в конец таблицы cars, а в таблице cust появляется запись с именем покупателя, идентификатором машины сданной в «trade-in» и id новой купленной машины: Чтобы реализовать SQL-запрос добавления записи в таблицу cust, нам нужно знать car_id автомобиля сданного в «trade-in». Предположим, что Федор еще не совершил покупку и таблица cars не содержит запись с его сданным автомобилем. Добавим ее. Выполним следующий запрос вот в такой программе:
with sq.connect("cars.db") as con: cur = con.cursor() cur.executescript("""CREATE TABLE IF NOT EXISTS cars ( car_id INTEGER PRIMARY KEY AUTOINCREMENT, model TEXT, price INTEGER ); CREATE TABLE IF NOT EXISTS cust(name TEXT, tr_in INTEGER, buy INTEGER); """) cur.execute("INSERT INTO cars VALUES(NULL,'Запорожец', 1000)")
Мы здесь создаем еще одну таблицу cust с тремя полями и, затем, добавляем в таблицу cars автомобиль «Запорожец», который сдает покупатель Федор. Как теперь нам узнать car_id этой записи? Для этого можно воспользоваться специальным свойством:
last_row_id = cur.lastrowid
которое содержит значение rowid последней добавленной записи. В нашем случае поля car_id и rowid будут совпадать, поэтому воспользуемся этим значением и сформируем еще один запрос на добавление записи во вторую таблицу:
buy_car_id = 2 cur.execute("INSERT INTO cust VALUES('Федор', ?, ?)", (last_row_id, buy_car_id))
Теперь, при выполнении нашей программы в таблице cust увидим искомую запись. Вот так используется свойство lastrowid. На этом завершим это занятие. На следующем продолжим рассматривать функционал API для работы с СУБД SQLite.
Python: Работа с базой данных, часть 1/2: Используем DB-API
Python DB-API – это не конкретная библиотека, а набор правил, которым подчиняются отдельные модули, реализующие работу с конкретными базами данных. Отдельные нюансы реализации для разных баз могут отличаться, но общие принципы позволяют использовать один и тот же подход при работе с разными базами данных.

В статье рассмотрены основные методы DB-API, позволяющие полноценно работать с базой данных. Полный список можете найти по ссылкам в конец статьи.
Требуемый уровень подготовки: базовое понимание синтаксиса SQL и Python.
Готовим инвентарь для дальнейшей комфортной работы
-
Python имеет встроенную поддержку SQLite базы данных, для этого вам не надо ничего дополнительно устанавливать, достаточно в скрипте указать импорт стандартной библиотеки
import sqlite3
Примечание: внося изменения в базу не забудьте их применить, так как база с непримененными изменениями остается залоченной.
Вы можете использовать (последние два варианта кросс-платформенные и бесплатные):
- Привычную вам утилиту для работы с базой в составе вашей IDE;
- SQLite Database Browser
- SQLiteStudio
Python DB-API модули в зависимости от базы данных
| База данных | DB-API модуль |
|---|---|
| SQLite | sqlite3 |
| PostgreSQL | psycopg2 |
| MySQL | mysql.connector |
| ODBC | pyodbc |
Соединение с базой, получение курсора
Для начала рассмотрим самый базовый шаблон DB-API, который будем использовать во всех дальнейших примерах:
# Импортируем библиотеку, соответствующую типу нашей базы данных import sqlite3 # Создаем соединение с нашей базой данных # В нашем примере у нас это просто файл базы conn = sqlite3.connect('Chinook_Sqlite.sqlite') # Создаем курсор - это специальный объект который делает запросы и получает их результаты cursor = conn.cursor() # ТУТ БУДЕТ НАШ КОД РАБОТЫ С БАЗОЙ ДАННЫХ # КОД ДАЛЬНЕЙШИХ ПРИМЕРОВ ВСТАВЛЯТЬ В ЭТО МЕСТО # Не забываем закрыть соединение с базой данных conn.close()
При работе с другими базами данных, используются дополнительные параметры соединения, например для PostrgeSQL:
conn = psycopg2.connect( host=hostname, user=username, password=password, dbname=database)
Чтение из базы
# Делаем SELECT запрос к базе данных, используя обычный SQL-синтаксис cursor.execute("SELECT Name FROM Artist ORDER BY Name LIMIT 3") # Получаем результат сделанного запроса results = cursor.fetchall() results2 = cursor.fetchall() print(results) # [('A Cor Do Som',), ('Aaron Copland & London Symphony Orchestra',), ('Aaron Goldberg',)] print(results2) # []
Обратите внимание: После получения результата из курсора, второй раз без повторения самого запроса его получить нельзя — вернется пустой результат!
Запись в базу
# Делаем INSERT запрос к базе данных, используя обычный SQL-синтаксис cursor.execute("insert into Artist values (Null, 'A Aagrh!') ") # Если мы не просто читаем, но и вносим изменения в базу данных - необходимо сохранить транзакцию conn.commit() # Проверяем результат cursor.execute("SELECT Name FROM Artist ORDER BY Name LIMIT 3") results = cursor.fetchall() print(results) # [('A Aagrh!',), ('A Cor Do Som',), ('Aaron Copland & London Symphony Orchestra',)]
Примечание: Если к базе установлено несколько соединений и одно из них осуществляет модификацю базы, то база SQLite залочивается до завершения (метод соединения .commit()) или отмены (метод соединения .rollback()) транзакции.
Разбиваем запрос на несколько строк в тройных кавычках
Длинные запросы можно разбивать на несколько строк в произвольном порядке, если они заключены в тройные кавычки — одинарные (»’…»’) или двойные («»». «»»)
cursor.execute(""" SELECT name FROM Artist ORDER BY Name LIMIT 3 """)
Конечно в таком простом примере разбивка не имеет смысла, но на сложных длинных запросах она может кардинально повышать читаемость кода.
Объединяем запросы к базе данных в один вызов метода
Метод курсора .execute() позволяет делать только один запрос за раз, при попытке сделать несколько через точку с запятой будет ошибка.
Для тех кто не верит на слово:
cursor.execute(""" insert into Artist values (Null, 'A Aagrh!'); insert into Artist values (Null, 'A Aagrh-2!'); """) # sqlite3.Warning: You can only execute one statement at a time.
Для решения такой задачи можно либо несколько раз вызывать метод курсора .execute()
cursor.execute("""insert into Artist values (Null, 'A Aagrh!');""") cursor.execute("""insert into Artist values (Null, 'A Aagrh-2!');""")
Либо использовать метод курсора .executescript()
cursor.executescript(""" insert into Artist values (Null, 'A Aagrh!'); insert into Artist values (Null, 'A Aagrh-2!'); """)
Данный метод также удобен, когда у нас запросы сохранены в отдельной переменной или даже в файле и нам его надо применить такой запрос к базе.
Делаем подстановку значения в запрос
Важно! Никогда, ни при каких условиях, не используйте конкатенацию строк (+) или интерполяцию параметра в строке (%) для передачи переменных в SQL запрос. Такое формирование запроса, при возможности попадания в него пользовательских данных – это ворота для SQL-инъекций!
Правильный способ – использование второго аргумента метода .execute()
Возможны два варианта:
# C подставновкой по порядку на места знаков вопросов: cursor.execute("SELECT Name FROM Artist ORDER BY Name LIMIT ?", ('2')) # И с использованием именнованных замен: cursor.execute("SELECT Name from Artist ORDER BY Name LIMIT :limit", )
Примечание 1: В PostgreSQL (UPD: и в MySQL) вместо знака ‘?’ для подстановки используется: %s
Примечание 2: Таким способом не получится заменять имена таблиц, одно из возможных решений в таком случае рассматривается тут: stackoverflow.com/questions/3247183/variable-table-name-in-sqlite/3247553#3247553
UPD: Примечание 3: Благодарю Igelko за упоминание параметра paramstyle — он определяет какой именно стиль используется для подстановки переменных в данном модуле.
Вот ссылка с полезным приемом для работы с разными стилями подстановок.
Делаем множественную вставку строк проходя по коллекции с помощью метода курсора .executemany()
# Обратите внимание, даже передавая одно значение - его нужно передавать кортежем! # Именно по этому тут используется запятая в скобках! new_artists = [ ('A Aagrh!',), ('A Aagrh!-2',), ('A Aagrh!-3',), ] cursor.executemany("insert into Artist values (Null, ?);", new_artists)
Получаем результаты по одному, используя метод курсора .fetchone()
Он всегда возвращает кортеж или None. если запрос пустой.
cursor.execute("SELECT Name FROM Artist ORDER BY Name LIMIT 3") print(cursor.fetchone()) # ('A Cor Do Som',) print(cursor.fetchone()) # ('Aaron Copland & London Symphony Orchestra',) print(cursor.fetchone()) # ('Aaron Goldberg',) print(cursor.fetchone()) # None
Важно! Стандартный курсор забирает все данные с сервера сразу, не зависимо от того, используем мы .fetchall() или .fetchone()
Курсор как итератор
# Использование курсора как итератора for row in cursor.execute('SELECT Name from Artist ORDER BY Name LIMIT 3'): print(row) # ('A Cor Do Som',) # ('Aaron Copland & London Symphony Orchestra',) # ('Aaron Goldberg',)
UPD: Повышаем устойчивость кода
Благодарю paratagas за ценное дополнение:
Для большей устойчивости программы (особенно при операциях записи) можно оборачивать инструкции обращения к БД в блоки «try-except-else» и использовать встроенный в sqlite3 «родной» объект ошибок, например, так:
try: cursor.execute(sql_statement) result = cursor.fetchall() except sqlite3.DatabaseError as err: print("Error: ", err) else: conn.commit()
UPD: Использование with в psycopg2
Благодарю KurtRotzke за ценное дополнение:
Последние версии psycopg2 позволяют делать так:
with psycopg2.connect("dbname='habr'") as conn: with conn.cursor() as cur:
Некоторые объекты в Python имеют __enter__ и __exit__ методы, что позволяет «чисто» взаимодействовать с ними, как в примере выше.
UPD: Ипользование row_factory
Благодарю remzalp за ценное дополнение:
Использование row_factory позволяет брать метаданные из запроса и обращаться в итоге к результату, например по имени столбца.
По сути — callback для обработки данных при возврате строки. Да еще и полезнейший cursor.description, где есть всё необходимое.
Пример из документации:
import sqlite3 def dict_factory(cursor, row): d = <> for idx, col in enumerate(cursor.description): d[col[0]] = row[idx] return d con = sqlite3.connect(":memory:") con.row_factory = dict_factory cur = con.cursor() cur.execute("select 1 as a") print(cur.fetchone()["a"])
Дополнительные материалы (на английском)
-
Краткий бесплатный он-лайн курс — Udacity — Intro to Relational Databases — Рассматриваются синтаксис и принципы работы SQL, Python DB-API – и теория и практика в одном флаконе. Очень рекомендую для начинающих!
- www.tutorialspoint.com/sql/index.htm
- www.tutorialspoint.com/sqlite
- www.sqlitetutorial.net
| часть 1/2: Используем DB-API | часть 2/2: Используем ORM |
|---|
Приглашаю к обсуждению:
- Если я где-то допустил неточность или не учёл что-то важное — пишите в комментариях, важные комментарии будут позже добавлены в статью с указанием вашего авторства.
- Если какие-то моменты не понятны и требуется уточнение — пишите ваши вопросы в комментариях — или я или другие читатели дадут ответ, а дельные вопросы с ответами будут позже добавлены в статью.
Выполнение транзакций в MySQL Python – свойства и методы
Выполнение транзакций в MySQL Python обеспечивает согласованность данных в базе данных. Мы должны убедиться, что несколько приложений не должны изменять записи при выполнении операций с базой данных. Транзакции обладают следующими свойствами:
- Атомарность.Либо транзакция завершается, либо ничего не происходит. Если транзакция содержит 4 запроса, то все эти запросы должны быть выполнены или ни один из них не должен быть выполнен.
- Последовательность.База данных должна быть согласованной до начала транзакции, а также после завершения транзакции.
- Изоляция.Промежуточные результаты транзакции не видны за пределами текущей сессии.
- Долговечность.После того, как транзакция была зафиксирована, эффекты сохраняются даже после сбоя системы.
Метод commit() в Python
Python предоставляет метод commit(), который обеспечивает внесение изменений в базу данных последовательно.
Синтаксис для использования метода commit() приведен ниже.
conn.commit() #conn is the connection object
Все операции, которые изменяют записи базы данных, не выполняются до тех пор, пока не будет вызвана функция commit().
Метод rollback()
Метод rollback() используется для отмены изменений, внесенных в базу данных. Этот метод полезен в том смысле, что, если во время операций с базой данных возникает какая-то ошибка, мы можем откатить эту транзакцию для поддержания согласованности базы данных.
Синтаксис использования функции rollback() приведен ниже.
Conn.rollback()
Закрытие соединения
Нам нужно закрыть соединение с базой данных после того, как мы выполнили все операции с ней. Python предоставляет метод close(). Синтаксис использования метода close() представлен ниже.
conn.close()
В следующем примере мы удалим всех сотрудников, которые работают в отделе CS.
import mysql.connector #Create the connection object myconn = mysql.connector.connect(host = "localhost", user = "root",passwd = "google",database = "PythonDB") #creating the cursor object cur = myconn.cursor() try: cur.execute("delete from Employee where Dept_id = 201") myconn.commit() print("Deleted !") except: print("Can't delete !") myconn.rollback() myconn.close()