June 13, 2023

Поменять статусы в Redmine, с помощью python

По одному из рабочих моментов, пришел запрос на изменение workflow. Довольно-таки фундаментальное.

Суть запроса была в следующем: на начальных этапах развития команды на одном из проектов, workflow был выбран по умолчанию. Статусы, трекеры задач были не созданы специально под проект, а взяты из уже имеющихся.

Соответственно, через некоторое время появилась насущная задача переделать workflow под себя. Для этого необходимо было:

1) создать новые статусы и трекеры

2) исправить старые статусы и трекеры в старых задачах на новые статусы и трекеры

Однако!

К тому времени на дашборде скопилось уже большое количество задач, терять которые команде не хотелось бы, соответственно, любая "работа руками" уперлась бы в гигантские потери времени.

Я решил эту задачу с помощью python, сэкономив время. Оставляю ниже схему и код, ведь redmine довольно популярен и это может быть кому-то полезно(да и другие таск-трекеры тоже иногда требуют вмешаться "ручками" и похардкодить).

Итак, код:

import yaml

import psycopg2

import csv

Соответственно, сначала импортируем те библиотеки, с которыми будем вести работу. psycopg2 - библиотека для работы с базами данных через python, она нам нужнее всего под данную задачу.

all_tasks=[]

Создаем список. В нем будут храниться все задачи, откуда мы достанем потом все id статусов.

with open('file.csv', encoding='utf-8') as file

rows = csv.DictReader(file, delimiter=',', quotechar='"')   

for row in rows:       

all_tasks.append(row)

Тут открываем файл, в котором содержатся все задачи (выгружен предварительно из БД, и записываем все задачи, со всеми данными в список, с которым потом будем вести работу).

conn = psycopg2.connect(dbname="", host="", user="", password="", port="")

Создаем подключение к БД. Соответственно, если мы хотим запустить скрипты через цикл и питон - это понадобится. Но можно будет запускать уже сформированные скрипты через Dbeaver, например, тогда не будет надобности в этой строчке кода.

Conn - это объект подлючения. Соответственно, в дальнейшем при работе с БД(при выборе работы через код) нужно будет обращаться к этому объекту, важно понимать зачем он, рекомендую почитать документацию, если возьметесь.

id_tasks_for_now={id_трекера:'Трекер',:'id_трекера:'Трекер,id_трекера:'Трекер}

id_tasks_for_replace={новое_id:'Трекер',новое_id:'Трекер',новое_id:'Трекер'}

Создаем два словаря. В один собираем те трекеры и айди, которые есть сейчас, в другой те трекеры, НА которые будем менять старые(которые, понятное дело, созданы предварительно и id которых заботливо выписано из БД).

Дальше просто, в зависимости от вашей персональной структуры трекеров, задач(и того, как именно таск-менеджер именно ваш шифрует задачи), делаем простой скрипт с минималистичными условиями:

for task in all_tasks:    #заходим в задачу или подзадачу и даем им обоим новый трекер и новое название    

if task['name_of_track']==id_tasks_for_now[айди] or task['name_of_track']==id_tasks_for_now[айди]:

        task['id_new_track']=id_tasks_for_replace[номер нового айди] #Новое айди трекера   

По такому же принципу выстраиваем все новые трекеры.

Дальше два варианта:

1) Можем записать в список запросы SQL и запустить через тот же dbeaver:

sql = 'UPDATE issues SET tracker_id=\'%s\',status_id=\'%s\' where project_key=\'%s\' and id=\'%s\''% (task['id_new_track'],task['id_new_stat'],task['project_key'],task['id_task'])

2) Можем сразу запиливать их в БД на обновление, допустим, так:

# #TODO: catch not found exceptions#    

cur = conn.cursor()#     print(sql)#    

cur.execute(sql)#    

conn.commit()#    

#record = cur.fetchone()

Вставляем в цикл и прогоняем эту строчку на каждой итерации. Тогда запрос на изменение БД, который вы формируете, сразу будет передан и отработан. Отнеситесь внимательно к этой строчке, в силу особенности библиотеки, если вы пропустите хоть одну строчку - ничего не будет работать и сохраняться.

Также десять раз подумайте перед тем, как пилить такое в коде сразу)) Можно легко переписать БД не подумав и потом от этого страдать.

Если какие-то вопросы будут, можете задавать в комментах. Схематично и логически шаги, думаю, понятны. А применить их к своей конкретной ситуации - это уже задачка на подумать.