Разбираюсь с БД. Написал пару скриптов(делающих одно и то же) для добавления пользователя в бд если его там нет. Оба варианта работают, но возник ряд вопросов.
Первый вариант.
- Здесь три запроса. Первые два выполняются в одной транзакции и еще один в другой? Логика была такая: если пользователь отсутствует, то сразу добавляем, иначе между поиском и добавлением может вклиниться еще один запрос и получится в таблице два пользователя с одинаковыми логинами.
- После последнего select нужно делать commit? Вообще, когда мы не вносим изменения commit делается?
import mysql.connector
dbconfig = {
'host': 'localhost',
'user': 'root',
'password': '010',
'database': 'testdb'
}
conn = mysql.connector.connect(**dbconfig)
cursor = conn.cursor()
login = 'user4'
cursor.execute("SELECT * FROM USER WHERE login=%s", (login,))
users = cursor.fetchall()
if len(users) == 0:
cursor.execute('INSERT INTO USER(login) VALUES(%s)', (login,))
conn.commit()
cursor.execute("SELECT * FROM USER WHERE login=%s", (login,))
users = cursor.fetchall()
if len(users) > 0:
print('Пользователь добавлен!')
else:
print('Ошибка записи')
else:
print('Пользователь существует!')
conn.commit()
cursor.close()
conn.close()
Второй вариант(использовал диспетчер контекста).
- Здесь все запросы выполняются в одной транзакции? Верно?
- Последний запрос(SELECT) видит изменения даже если коммит не выполнен. Я так понимаю изменения кешируются и запросы на выборку тоже учитывают эти не примененные изменения? Если так, то всегда ли эти изменения(до выполнения commit) будут учитываться?
- Если все действия успешно выполнены(три запроса) может commit(в exit) не выполниться?
import mysql.connector
dbconfig = {
'host': 'localhost',
'user': 'root',
'password': '010',
'database': 'testdb'
}
class UseDatabase:
def __init__(self, config: dict) -> None:
self.configuration = config
def __enter__(self) -> 'cursor':
self.conn = mysql.connector.connect(**self.configuration)
self.cursor = self.conn.cursor()
return self.cursor
def __exit__(self, exc_type, exc_value, exc_trace) -> None:
self.conn.commit()
self.cursor.close()
self.conn.close()
with UseDatabase(dbconfig) as cursor:
login = 'user1'
cursor.execute("SELECT * FROM USER WHERE login=%s", (login,))
users = cursor.fetchall()
if len(users) == 0:
cursor.execute('INSERT INTO USER(login) VALUES(%s)', (login,))
cursor.execute("SELECT * FROM USER WHERE login=%s", (login,))
users = cursor.fetchall()
if len(users) > 0:
print('Пользователь добавлен!')
else:
print('Ошибка записи')
else:
print('Пользователь существует!')