2 минут чтения
21 февраля 2021 г.
Транзакции в SQLAlchemy
Транзакция — последовательность действий, связанных с базой данных. Их основная польза заключается в том, что при возникновении какой-то ошибки или достижении других нужных условий всю транзакцию можно отменить, и все изменения, примененные к базе данных, будут отменены. Сегодня мы напишем небольшой скрипт, который при помощи транзакций SQLAlchemy пишет информацию о подписчиках сообщества в базу данных MySQL, а при возникновении ошибки отменяет текущую транзакцию.
Сбор информации об участниках через VK API
Для начала напишем пару маленьких функций — первая будет возвращать число подписчиков сообщества, а вторая — отправлять запрос и формировать датафрейм с информацией о подписчиках сообщества.
Подробнее о том, как получить токен, можно прочитать в материале «Собираем данные по рекламным кампаниям ВКонтакте»
from sqlalchemy import create_engine
import pandas as pd
import requests
import time
token = ’42hj2ehd3djdournf48fjurhf9r9o2eurnf48fjurhf9r9734′
group_id = ‘leftjoin’
Чтобы узнать число подписчиков достаточно отправить метод groups.getMembers с любыми параметрами — в ответе всегда возвращается количество в поле count.
def get_subs_count(group_id):
count = requests.get(‘https://api.vk.com/method/groups.getMembers’, params={
‘access_token’:token,
‘v’:5.103,
‘group_id’:group_id
}).json()[‘response’][‘count’]
return count
Для примера будем брать имена, id, фамилии подписчиков, некоторую расширенную информацию и получать только по 10 подписчиков за раз, чтобы рассмотреть работу транзакций детально — каждые 10 подписчиков будут вставляться одной транзакцией. Введём дополнительное поле offset, чтобы знать, в какой итерации добавлены строки.
def get_subs_info(group_id, offset):
response = requests.get(‘https://api.vk.com/method/groups.getMembers’, params={
‘access_token’:token,
‘v’:5.103,
‘group_id’:group_id,
‘offset’:offset,
‘count’:10,
‘fields’:’sex, has_mobile, relation, can_post’
}).json()[‘response’][‘items’]
df = pd.DataFrame(response)
df[‘offset’] = offset
return df
Транзакции
Наконец, можем подсоединиться к базе данных при помощи SQLAlchemy:
engine = create_engine(‘mysql+mysqlconnector://’ +
‘root’ + ‘:’ + » + ‘@’ +
‘localhost’ + ‘/’ +
‘transaction’, echo=False)
У транзакций всегда должно быть начало — begin, и конец — commit. В случае, если произошла какая-то ошибка, можно сделать откат — rollback. Сперва получаем число подписчиков сообщество, и в каждой итерации цикла при помощи контекстного менеджера with … as создаём новое подключение. Сразу после объявляем начало транзакции по этому подключению и с обработчиком исключений пробуем получить информацию о десяти подписчиках через функцию get_subs_info. Вставляем полученный датафрейм в таблицу методом to_sql и завершаем транзакцию при помощи метода commit(). В случае, если возникла какая-то ошибка — печатаем её на экран и отменяем транзакцию.
<?php
offset = 0
subs_count = get_subs_count(group_id)
while offset < subs_count:
with engine.connect() as conn:
transaction = conn.begin()
try:
df = get_subs_info(group_id, offset)
df.to_sql('subscribers', con=conn, if_exists='append', index=False)
transaction.commit()
except Exception as E:
print(E)
transaction.rollback()
time.sleep(1)
offset += 10
?>
Чтобы протестировать работу транзакций слегка обновим последний блок кода — добавим вызов ошибки ValueError после вставки данных в базу, если текущий offset равен 10.
<?php
offset = 0
subs_count = get_subs_count(group_id)
while offset < subs_count:
with engine.connect() as conn:
transaction = conn.begin()
try:
df = get_subs_info(group_id, offset)
df.to_sql('subscribers', con=conn, if_exists='append', index=False)
if offset == 10:
raise(ValueError)
transaction.commit()
except Exception as E:
print(E)
transaction.rollback()
time.sleep(1)
offset += 10
?>
Как и планировалось, данные за итерацию с offset = 10 не занесены в таблицу. Несмотря на то, что ошибка возникла уже после добавления новых данных, транзакция была прервана методом rollback() и завершение транзакции было отменено.
[ Рекомендации ]
Читайте также
2 минут чтения
20 сентября 2020
[ Связаться ]
Давайте раскроем потенциал вашего бизнеса вместе
Заполните форму на бесплатную консультацию