From 7be18af635d079e1359c9f84dd375b1671fb1a62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Thu, 9 Nov 2017 11:51:00 -0200 Subject: [PATCH 01/14] =?UTF-8?q?Cria=C3=A7=C3=A3o=20da=20fun=C3=A7=C3=A3o?= =?UTF-8?q?=20de=20merge=20de=20autor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/migra_autor.py | 46 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 sapl/legacy/migra_autor.py diff --git a/sapl/legacy/migra_autor.py b/sapl/legacy/migra_autor.py new file mode 100644 index 000000000..10372c9d9 --- /dev/null +++ b/sapl/legacy/migra_autor.py @@ -0,0 +1,46 @@ +import mysql.connector # dep: mysql-connector-python-rf + +def migra_autor(db, passwd): + connection = mysql.connector.connect(user='root', database=db, passwd=passwd) + cursor = connection.cursor(buffered=True) + query = ("select cod_parlamentar, COUNT(*) \ + from {}.autor where col_username is not null \ + group by col_username, cod_parlamentar \ + having 1 < COUNT(*) \ + order by cod_parlamentar asc;").format(db) + + cursor.execute(query) + + all_authors = [] + for response in cursor: + if response[0] is not None: + all_authors.append(response) + + + for author in all_authors: + query2 = ("select * from {}.autor \ + where cod_parlamentar = " + str(author[0]) + " \ + group by cod_autor;").format(db) + cursor.execute(query2) + user = [] + for response in cursor: + user.append(response) + + ativ = [] + inativ = [] + for tupl in user: + if tupl[8] == 1: + inativ.append(tupl) + elif tupl[8] == 0: + ativ.append(tupl) + + + tables = ['autoria', 'documento_administrativo', 'proposicao', 'protocolo'] + for table in tables: + query3 = ("UPDATE {}.{} SET cod_autor = {} WHERE cod_autor in ").format(db, table, ativ[0][0]) + inativIds = [u[0] for u in inativ] + inativIds = (str(inativIds)).replace(']', ')').replace('[', '(') + query3 += inativIds + + cursor.execute(query3) + \ No newline at end of file From 911c3e10f22087f6373743dae7bf28f757260814 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Thu, 9 Nov 2017 13:35:42 -0200 Subject: [PATCH 02/14] Corrige alguns problemas --- sapl/legacy/migra_autor.py | 90 ++++++++++++++++++++------------------ 1 file changed, 48 insertions(+), 42 deletions(-) diff --git a/sapl/legacy/migra_autor.py b/sapl/legacy/migra_autor.py index 10372c9d9..dbe6404eb 100644 --- a/sapl/legacy/migra_autor.py +++ b/sapl/legacy/migra_autor.py @@ -1,46 +1,52 @@ import mysql.connector # dep: mysql-connector-python-rf def migra_autor(db, passwd): - connection = mysql.connector.connect(user='root', database=db, passwd=passwd) - cursor = connection.cursor(buffered=True) - query = ("select cod_parlamentar, COUNT(*) \ - from {}.autor where col_username is not null \ - group by col_username, cod_parlamentar \ - having 1 < COUNT(*) \ - order by cod_parlamentar asc;").format(db) - - cursor.execute(query) - - all_authors = [] - for response in cursor: - if response[0] is not None: - all_authors.append(response) - - - for author in all_authors: - query2 = ("select * from {}.autor \ - where cod_parlamentar = " + str(author[0]) + " \ - group by cod_autor;").format(db) - cursor.execute(query2) - user = [] + connection = mysql.connector.connect(user='root', database=db, passwd=passwd) + cursor = connection.cursor(buffered=True) + query = ("select cod_parlamentar, COUNT(*) \ + from {}.autor where col_username is not null \ + group by col_username, cod_parlamentar \ + having 1 < COUNT(*) \ + order by cod_parlamentar asc;").format(db) + + cursor.execute(query) + + all_authors = [] for response in cursor: - user.append(response) - - ativ = [] - inativ = [] - for tupl in user: - if tupl[8] == 1: - inativ.append(tupl) - elif tupl[8] == 0: - ativ.append(tupl) - - - tables = ['autoria', 'documento_administrativo', 'proposicao', 'protocolo'] - for table in tables: - query3 = ("UPDATE {}.{} SET cod_autor = {} WHERE cod_autor in ").format(db, table, ativ[0][0]) - inativIds = [u[0] for u in inativ] - inativIds = (str(inativIds)).replace(']', ')').replace('[', '(') - query3 += inativIds - - cursor.execute(query3) - \ No newline at end of file + if response[0] is not None: + all_authors.append(response) + + + for author in all_authors: + query2 = ("select * from {}.autor \ + where cod_parlamentar = " + str(author[0]) + " \ + group by cod_autor;").format(db) + cursor.execute(query2) + user = [] + + for response in cursor: + user.append(response) + + ativ = [] + inativ = [] + for tupl in user: + if tupl[8] == 1: + inativ.append(tupl) + elif tupl[8] == 0: + ativ.append(tupl) + + + tables = ['autoria', 'documento_administrativo', 'proposicao', 'protocolo'] + for table in tables: + # Para update e delete no MySQL -> SET SQL_SAFE_UPDATES = 0; + query3 = ("update {}.{} set cod_autor = {} where cod_autor in ").format(db, table, ativ[0][0]) + inativIds = [u[0] for u in inativ] + inativIds = (str(inativIds)).replace(']', ')').replace('[', '(') + query3 += inativIds + ';' + #cursor.execute(query3) + + + query4 = ("delete from sapl_cm_ere_cpy.autor \ + where cod_autor in ") + query4 += inativIds + ';' + From 4063760b5fd5d9bb49363f966830574d8b840bf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Thu, 9 Nov 2017 14:00:25 -0200 Subject: [PATCH 03/14] =?UTF-8?q?Pequenas=20corre=C3=A7=C3=B5es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/migra_autor.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sapl/legacy/migra_autor.py b/sapl/legacy/migra_autor.py index dbe6404eb..d806f510e 100644 --- a/sapl/legacy/migra_autor.py +++ b/sapl/legacy/migra_autor.py @@ -19,8 +19,8 @@ def migra_autor(db, passwd): for author in all_authors: query2 = ("select * from {}.autor \ - where cod_parlamentar = " + str(author[0]) + " \ - group by cod_autor;").format(db) + where cod_parlamentar = {} \ + group by cod_autor;").format(db, str(author[0])) cursor.execute(query2) user = [] @@ -30,6 +30,7 @@ def migra_autor(db, passwd): ativ = [] inativ = [] for tupl in user: + # tupl[8] = ind_excluido if tupl[8] == 1: inativ.append(tupl) elif tupl[8] == 0: @@ -43,10 +44,11 @@ def migra_autor(db, passwd): inativIds = [u[0] for u in inativ] inativIds = (str(inativIds)).replace(']', ')').replace('[', '(') query3 += inativIds + ';' - #cursor.execute(query3) + cursor.execute(query3) query4 = ("delete from sapl_cm_ere_cpy.autor \ where cod_autor in ") query4 += inativIds + ';' + cursor.execute(query4) From 1488df9cf3bfea6a59eee5838596c00a062c8ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Thu, 9 Nov 2017 15:47:33 -0200 Subject: [PATCH 04/14] Incorpora o migra_autor para o migration --- sapl/legacy/migra_autor.py | 54 ---------------------------------- sapl/legacy/migration.py | 59 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 54 deletions(-) delete mode 100644 sapl/legacy/migra_autor.py diff --git a/sapl/legacy/migra_autor.py b/sapl/legacy/migra_autor.py deleted file mode 100644 index d806f510e..000000000 --- a/sapl/legacy/migra_autor.py +++ /dev/null @@ -1,54 +0,0 @@ -import mysql.connector # dep: mysql-connector-python-rf - -def migra_autor(db, passwd): - connection = mysql.connector.connect(user='root', database=db, passwd=passwd) - cursor = connection.cursor(buffered=True) - query = ("select cod_parlamentar, COUNT(*) \ - from {}.autor where col_username is not null \ - group by col_username, cod_parlamentar \ - having 1 < COUNT(*) \ - order by cod_parlamentar asc;").format(db) - - cursor.execute(query) - - all_authors = [] - for response in cursor: - if response[0] is not None: - all_authors.append(response) - - - for author in all_authors: - query2 = ("select * from {}.autor \ - where cod_parlamentar = {} \ - group by cod_autor;").format(db, str(author[0])) - cursor.execute(query2) - user = [] - - for response in cursor: - user.append(response) - - ativ = [] - inativ = [] - for tupl in user: - # tupl[8] = ind_excluido - if tupl[8] == 1: - inativ.append(tupl) - elif tupl[8] == 0: - ativ.append(tupl) - - - tables = ['autoria', 'documento_administrativo', 'proposicao', 'protocolo'] - for table in tables: - # Para update e delete no MySQL -> SET SQL_SAFE_UPDATES = 0; - query3 = ("update {}.{} set cod_autor = {} where cod_autor in ").format(db, table, ativ[0][0]) - inativIds = [u[0] for u in inativ] - inativIds = (str(inativIds)).replace(']', ')').replace('[', '(') - query3 += inativIds + ';' - cursor.execute(query3) - - - query4 = ("delete from sapl_cm_ere_cpy.autor \ - where cod_autor in ") - query4 += inativIds + ';' - cursor.execute(query4) - diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index f61f564ff..e72f50e45 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -181,6 +181,65 @@ def garante_tabela_no_legado(create_table): assert existe_tabela_no_legado(tabela) +def migra_autor(): + SQL_ENUMERA_REPETIDOS = ''' + select cod_parlamentar, COUNT(*) + from autor where col_username is not null + group by col_username, cod_parlamentar + having 1 < COUNT(*) + order by cod_parlamentar asc; + ''' + + SQL_INFOS_AUTOR = ''' + select * from autor + where cod_parlamentar = {} + group by cod_autor; + ''' + + SQL_UPDATE_TABLES_AUTOR = "update {} set cod_autor = {} where cod_autor in ({});" + + SQL_DELETE_AUTOR_INATIVO = "delete from autor where cod_autor in ({});" + + cursor = exec_legado(SQL_ENUMERA_REPETIDOS) + + all_authors = [] + + for response in cursor: + if response[0] is not None: + all_authors.append(response) + + for author in all_authors: + sql = SQL_INFOS_AUTOR.format(str(author[0])) + cursor = exec_legado(sql) + + user = [] + + for response in cursor: + user.append(response) + + ativ = [] + inativ = [] + for tupl in user: + # tupl[8] = ind_excluido + if tupl[8] == 1: + inativ.append(tupl) + elif tupl[8] == 0:\ + ativ.append(tupl) + + tables = ['autoria', 'documento_administrativo', 'proposicao', 'protocolo'] + for table in tables: + # Para update e delete no MySQL -> SET SQL_SAFE_UPDATES = 0; + ativId = ativ[0][0] + inativIds = [u[0] for u in inativ] + inativIds = (str(inativIds)).replace(']', '').replace('[', '') + sql = SQL_UPDATE_TABLES_AUTOR.format(table, ativId, inativIds) + exec_legado(sql) + + + sql = SQL_DELETE_AUTOR_INATIVO.format(inativIds) + exec_legado(sql) + + def uniformiza_banco(): exec_legado(''' SELECT replace(@@sql_mode,"STRICT_TRANS_TABLES,","ALLOW_INVALID_DATES"); From e8e404f9bc1fd717713b41391059588f576a1666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Thu, 9 Nov 2017 18:21:59 -0200 Subject: [PATCH 05/14] =?UTF-8?q?Verifica=20a=20repeti=C3=A7=C3=A3o=20em?= =?UTF-8?q?=20materias?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/migration.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index e72f50e45..8e2b5948d 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -200,6 +200,16 @@ def migra_autor(): SQL_DELETE_AUTOR_INATIVO = "delete from autor where cod_autor in ({});" + SQL_ENUMERA_AUTORIA_REPETIDOS = ''' + select cod_materia, COUNT(*) from autoria where cod_autor in ({}) + group by cod_materia + having 1 < COUNT(*); + ''' + + SQL_INFO_AUTORIA = ''' + select * from autoria where cod_materia = {} and cod_autor in ({}); + ''' + cursor = exec_legado(SQL_ENUMERA_REPETIDOS) all_authors = [] @@ -223,7 +233,7 @@ def migra_autor(): # tupl[8] = ind_excluido if tupl[8] == 1: inativ.append(tupl) - elif tupl[8] == 0:\ + elif tupl[8] == 0: ativ.append(tupl) tables = ['autoria', 'documento_administrativo', 'proposicao', 'protocolo'] @@ -232,6 +242,15 @@ def migra_autor(): ativId = ativ[0][0] inativIds = [u[0] for u in inativ] inativIds = (str(inativIds)).replace(']', '').replace('[', '') + + sql = SQL_ENUMERA_AUTORIA_REPETIDOS.format(ativId + ', ' + inativIds) + cursor = exec_legado(sql) + + for response in cursor: + sql = SQL_INFO_AUTORIA.format(response[0], ativId + ', ' + inativIds) + materias = exec_legado(sql) + + sql = SQL_UPDATE_TABLES_AUTOR.format(table, ativId, inativIds) exec_legado(sql) From ad1682e393a1c941804b50f363e0e2494a358bed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Mon, 13 Nov 2017 11:04:57 -0200 Subject: [PATCH 06/14] =?UTF-8?q?Verifica=20repeti=C3=A7=C3=B5es=20em=20au?= =?UTF-8?q?toria?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/migration.py | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 8e2b5948d..3d20384f6 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -182,6 +182,10 @@ def garante_tabela_no_legado(create_table): def migra_autor(): + SQL_ALTERA_IND_EXCLUIDO = ''' + update {} set ind_excluido = null; + ''' + SQL_ENUMERA_REPETIDOS = ''' select cod_parlamentar, COUNT(*) from autor where col_username is not null @@ -210,6 +214,11 @@ def migra_autor(): select * from autoria where cod_materia = {} and cod_autor in ({}); ''' + SQL_DELETE_AUTORIA = ''' + delete from autoria where cod_materia in ({}) and cod_autor in ({}); + ''' + + cursor = exec_legado(SQL_ALTERA_IND_EXCLUIDO.format('autor')) cursor = exec_legado(SQL_ENUMERA_REPETIDOS) all_authors = [] @@ -227,38 +236,29 @@ def migra_autor(): for response in cursor: user.append(response) - ativ = [] - inativ = [] - for tupl in user: - # tupl[8] = ind_excluido - if tupl[8] == 1: - inativ.append(tupl) - elif tupl[8] == 0: - ativ.append(tupl) + last = user.pop(len(user) - 1) + ativId = last[0] + inativIds =[u[0] for u in user] tables = ['autoria', 'documento_administrativo', 'proposicao', 'protocolo'] for table in tables: # Para update e delete no MySQL -> SET SQL_SAFE_UPDATES = 0; - ativId = ativ[0][0] - inativIds = [u[0] for u in inativ] inativIds = (str(inativIds)).replace(']', '').replace('[', '') sql = SQL_ENUMERA_AUTORIA_REPETIDOS.format(ativId + ', ' + inativIds) cursor = exec_legado(sql) for response in cursor: - sql = SQL_INFO_AUTORIA.format(response[0], ativId + ', ' + inativIds) - materias = exec_legado(sql) + if table == 'autoria': + sql = SQL_INFO_AUTORIA.format(response[0], ativId + ', ' + inativIds) + materias = exec_legado(sql) + sql = SQL_DELETE_AUTORIA.format(response[0], inativIds) sql = SQL_UPDATE_TABLES_AUTOR.format(table, ativId, inativIds) exec_legado(sql) - sql = SQL_DELETE_AUTOR_INATIVO.format(inativIds) - exec_legado(sql) - - def uniformiza_banco(): exec_legado(''' SELECT replace(@@sql_mode,"STRICT_TRANS_TABLES,","ALLOW_INVALID_DATES"); From 8924afd1f97108a6a658b2938d0f451c545c4b33 Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Mon, 13 Nov 2017 11:55:47 -0200 Subject: [PATCH 07/14] Ajusta pre migracao de autor --- sapl/legacy/migration.py | 57 ++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 34 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 3d20384f6..38647a460 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -4,8 +4,9 @@ from functools import lru_cache, partial from subprocess import PIPE, call import pkg_resources -import reversion import yaml + +import reversion from django.apps import apps from django.apps.config import AppConfig from django.contrib.auth import get_user_model @@ -15,7 +16,6 @@ from django.core.exceptions import ObjectDoesNotExist from django.db import connections, transaction from django.db.models import Count, Max from django.db.models.base import ModelBase - from sapl.base.models import AppConfig as AppConf from sapl.base.models import (Autor, CasaLegislativa, ProblemaMigracao, TipoAutor) @@ -146,6 +146,7 @@ def exec_sql(sql, db='default'): # UNIFORMIZAÇÃO DO BANCO ANTES DA MIGRAÇÃO ############################### + SQL_NAO_TEM_TABELA = ''' SELECT count(*) FROM information_schema.columns @@ -182,9 +183,6 @@ def garante_tabela_no_legado(create_table): def migra_autor(): - SQL_ALTERA_IND_EXCLUIDO = ''' - update {} set ind_excluido = null; - ''' SQL_ENUMERA_REPETIDOS = ''' select cod_parlamentar, COUNT(*) @@ -195,8 +193,8 @@ def migra_autor(): ''' SQL_INFOS_AUTOR = ''' - select * from autor - where cod_parlamentar = {} + select cod_autor from autor + where cod_parlamentar = {} group by cod_autor; ''' @@ -215,47 +213,38 @@ def migra_autor(): ''' SQL_DELETE_AUTORIA = ''' - delete from autoria where cod_materia in ({}) and cod_autor in ({}); + delete from autoria where cod_materia in ({}) and cod_autor in ({}); ''' - cursor = exec_legado(SQL_ALTERA_IND_EXCLUIDO.format('autor')) + cursor = exec_legado('update autor set ind_excluido = null;') cursor = exec_legado(SQL_ENUMERA_REPETIDOS) - all_authors = [] + autores_parlamentares = [r[0] for r in cursor if r[0]] - for response in cursor: - if response[0] is not None: - all_authors.append(response) + for cod_autor in autores_parlamentares: - for author in all_authors: - sql = SQL_INFOS_AUTOR.format(str(author[0])) - cursor = exec_legado(sql) - - user = [] - - for response in cursor: - user.append(response) + sql = SQL_INFOS_AUTOR.format(cod_autor) - last = user.pop(len(user) - 1) - ativId = last[0] - inativIds =[u[0] for u in user] + cursor = exec_legado(sql) + autores = cursor.fetch_all() + ids = [a[0] for a in autores] + id_ativo, ids_inativos = ids[-1], ids[:-1] - tables = ['autoria', 'documento_administrativo', 'proposicao', 'protocolo'] - for table in tables: + tabelas = ['autoria', 'documento_administrativo', + 'proposicao', 'protocolo'] + for tabela in tabelas: # Para update e delete no MySQL -> SET SQL_SAFE_UPDATES = 0; - inativIds = (str(inativIds)).replace(']', '').replace('[', '') + ids_inativos = str(ids_inativos).strip('[]') - sql = SQL_ENUMERA_AUTORIA_REPETIDOS.format(ativId + ', ' + inativIds) + sql = SQL_ENUMERA_AUTORIA_REPETIDOS.format(str(ids).strip('[]')) cursor = exec_legado(sql) for response in cursor: - if table == 'autoria': - sql = SQL_INFO_AUTORIA.format(response[0], ativId + ', ' + inativIds) - materias = exec_legado(sql) - sql = SQL_DELETE_AUTORIA.format(response[0], inativIds) - + if tabela == 'autoria': + sql = SQL_DELETE_AUTORIA.format(response[0], ids_inativos) - sql = SQL_UPDATE_TABLES_AUTOR.format(table, ativId, inativIds) + sql = SQL_UPDATE_TABLES_AUTOR.format( + tabela, id_ativo, ids_inativos) exec_legado(sql) From 66d598520357f4f551adadd8cbba9a6a11f844bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Tue, 14 Nov 2017 14:56:47 -0200 Subject: [PATCH 08/14] =?UTF-8?q?Corrige=20alguns=20erros=20de=20execu?= =?UTF-8?q?=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/migration.py | 30 ++++++++++++++++++++---------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 38647a460..f3f6be126 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -216,7 +216,7 @@ def migra_autor(): delete from autoria where cod_materia in ({}) and cod_autor in ({}); ''' - cursor = exec_legado('update autor set ind_excluido = null;') + #cursor = exec_legado('update autor set ind_excluido = null;') cursor = exec_legado(SQL_ENUMERA_REPETIDOS) autores_parlamentares = [r[0] for r in cursor if r[0]] @@ -226,26 +226,36 @@ def migra_autor(): sql = SQL_INFOS_AUTOR.format(cod_autor) cursor = exec_legado(sql) - autores = cursor.fetch_all() + autores = [] + + for response in cursor: + autores.append(response) + ids = [a[0] for a in autores] id_ativo, ids_inativos = ids[-1], ids[:-1] tabelas = ['autoria', 'documento_administrativo', 'proposicao', 'protocolo'] for tabela in tabelas: - # Para update e delete no MySQL -> SET SQL_SAFE_UPDATES = 0; - ids_inativos = str(ids_inativos).strip('[]') + if tabela == 'autoria': + # Para update e delete no MySQL -> SET SQL_SAFE_UPDATES = 0; + ids_inativos = str(ids_inativos).strip('[]') + + sql = SQL_ENUMERA_AUTORIA_REPETIDOS.format(str(ids).strip('[]')) + cursor = exec_legado(sql) - sql = SQL_ENUMERA_AUTORIA_REPETIDOS.format(str(ids).strip('[]')) - cursor = exec_legado(sql) + materias = [] + for response in cursor: + materias.append(response[0]) - for response in cursor: - if tabela == 'autoria': - sql = SQL_DELETE_AUTORIA.format(response[0], ids_inativos) + sql = SQL_DELETE_AUTORIA.format(str(materias).strip('[]'), ids_inativos) + import ipdb + ipdb.set_trace() + print('') sql = SQL_UPDATE_TABLES_AUTOR.format( tabela, id_ativo, ids_inativos) - exec_legado(sql) + #exec_legado(sql) def uniformiza_banco(): From 1c4ed3deaab6e964c95cb43d5f89d5356d14fd3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Tue, 14 Nov 2017 15:42:58 -0200 Subject: [PATCH 09/14] Adiciona o update nas demais tabelas --- sapl/legacy/migration.py | 58 ++++++++++++++++++++++++++++------------ 1 file changed, 41 insertions(+), 17 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index f3f6be126..97750c628 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -198,9 +198,7 @@ def migra_autor(): group by cod_autor; ''' - SQL_UPDATE_TABLES_AUTOR = "update {} set cod_autor = {} where cod_autor in ({});" - - SQL_DELETE_AUTOR_INATIVO = "delete from autor where cod_autor in ({});" + SQL_UPDATE_AUTOR = "update autoria set cod_autor = {} where cod_autor in ({});" SQL_ENUMERA_AUTORIA_REPETIDOS = ''' select cod_materia, COUNT(*) from autoria where cod_autor in ({}) @@ -208,14 +206,28 @@ def migra_autor(): having 1 < COUNT(*); ''' - SQL_INFO_AUTORIA = ''' - select * from autoria where cod_materia = {} and cod_autor in ({}); - ''' - SQL_DELETE_AUTORIA = ''' delete from autoria where cod_materia in ({}) and cod_autor in ({}); ''' + SQL_UPDATE_DOCUMENTO_ADMINISTRATIVO = ''' + update documento_administrativo + set cod_autor = {} + where cod_autor in ({}); + ''' + + SQL_UPDATE_PROPOSICAO = ''' + update proposicao + set cod_autor = {} + where cod_autor in ({}); + ''' + + SQL_UPDATE_PROTOCOLO = ''' + update protocolo + set cod_autor = {} + where cod_autor in ({}); + ''' + #cursor = exec_legado('update autor set ind_excluido = null;') cursor = exec_legado(SQL_ENUMERA_REPETIDOS) @@ -233,29 +245,41 @@ def migra_autor(): ids = [a[0] for a in autores] id_ativo, ids_inativos = ids[-1], ids[:-1] + ids = str(ids).strip('[]') + id_ativo = str(id_ativo).strip('[]') + ids_inativos = str(ids_inativos).strip('[]') tabelas = ['autoria', 'documento_administrativo', 'proposicao', 'protocolo'] for tabela in tabelas: if tabela == 'autoria': # Para update e delete no MySQL -> SET SQL_SAFE_UPDATES = 0; - ids_inativos = str(ids_inativos).strip('[]') - - sql = SQL_ENUMERA_AUTORIA_REPETIDOS.format(str(ids).strip('[]')) + sql = SQL_ENUMERA_AUTORIA_REPETIDOS.format(ids) cursor = exec_legado(sql) materias = [] for response in cursor: materias.append(response[0]) - sql = SQL_DELETE_AUTORIA.format(str(materias).strip('[]'), ids_inativos) - import ipdb - ipdb.set_trace() - print('') + materias = str(materias).strip('[]') + + sql = SQL_DELETE_AUTORIA.format(materias, ids_inativos) + exec_legado(sql) + + sql = SQL_UPDATE_AUTOR.format(id_ativo, ids_inativos) + exec_legado(sql) + + elif tabela == 'documento_administrativo': + sql = SQL_UPDATE_DOCUMENTO_ADMINISTRATIVO.format(id_ativo, ids_inativos) + exec_legado(sql) + + elif tabela == 'proposicao': + sql = SQL_UPDATE_PROPOSICAO.format(id_ativo, ids_inativos) + exec_legado(sql) - sql = SQL_UPDATE_TABLES_AUTOR.format( - tabela, id_ativo, ids_inativos) - #exec_legado(sql) + elif tabela == 'protocolo': + sql = SQL_UPDATE_PROTOCOLO.format(id_ativo, ids_inativos) + exec_legado(sql) def uniformiza_banco(): From f47d8d2b17116811ded8693834fb186b84112764 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Tue, 14 Nov 2017 15:50:05 -0200 Subject: [PATCH 10/14] =?UTF-8?q?Verifica=20se=20h=C3=A1=20os=20IDs=20e=20?= =?UTF-8?q?Materias=20antes=20da=20execu=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/migration.py | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 97750c628..210c8c5ef 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -211,8 +211,8 @@ def migra_autor(): ''' SQL_UPDATE_DOCUMENTO_ADMINISTRATIVO = ''' - update documento_administrativo - set cod_autor = {} + update documento_administrativo + set cod_autor = {} where cod_autor in ({}); ''' @@ -228,7 +228,7 @@ def migra_autor(): where cod_autor in ({}); ''' - #cursor = exec_legado('update autor set ind_excluido = null;') + cursor = exec_legado('update autor set ind_excluido = 0;') cursor = exec_legado(SQL_ENUMERA_REPETIDOS) autores_parlamentares = [r[0] for r in cursor if r[0]] @@ -252,7 +252,7 @@ def migra_autor(): tabelas = ['autoria', 'documento_administrativo', 'proposicao', 'protocolo'] for tabela in tabelas: - if tabela == 'autoria': + if tabela == 'autoria' and id_ativo and ids_inativos: # Para update e delete no MySQL -> SET SQL_SAFE_UPDATES = 0; sql = SQL_ENUMERA_AUTORIA_REPETIDOS.format(ids) cursor = exec_legado(sql) @@ -262,22 +262,22 @@ def migra_autor(): materias.append(response[0]) materias = str(materias).strip('[]') - - sql = SQL_DELETE_AUTORIA.format(materias, ids_inativos) - exec_legado(sql) + if materias: + sql = SQL_DELETE_AUTORIA.format(materias, ids_inativos) + exec_legado(sql) sql = SQL_UPDATE_AUTOR.format(id_ativo, ids_inativos) exec_legado(sql) - elif tabela == 'documento_administrativo': + elif tabela == 'documento_administrativo' and id_ativo and ids_inativos: sql = SQL_UPDATE_DOCUMENTO_ADMINISTRATIVO.format(id_ativo, ids_inativos) exec_legado(sql) - elif tabela == 'proposicao': + elif tabela == 'proposicao' and id_ativo and ids_inativos: sql = SQL_UPDATE_PROPOSICAO.format(id_ativo, ids_inativos) exec_legado(sql) - elif tabela == 'protocolo': + elif tabela == 'protocolo' and id_ativo and ids_inativos: sql = SQL_UPDATE_PROTOCOLO.format(id_ativo, ids_inativos) exec_legado(sql) @@ -362,6 +362,8 @@ relatoria | tip_fim_relatoria = NULL | tip_fim_relatoria = 0 spec = spec.split('|') exec_legado('UPDATE {} SET {} WHERE {}'.format(*spec)) + migra_autor() # Migra autores para um único autor + def iter_sql_records(sql, db): class Record: From ee78734922e6e1c590c7dcf0fb61fed9390a050c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Tue, 21 Nov 2017 13:28:25 -0200 Subject: [PATCH 11/14] =?UTF-8?q?Adiciona=20a=20exclus=C3=A3o=20dos=20dema?= =?UTF-8?q?is=20autores?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Exclui os autores e mantém apenas um registro para a migração --- sapl/legacy/migration.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 210c8c5ef..140e9836c 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -228,6 +228,11 @@ def migra_autor(): where cod_autor in ({}); ''' + SQL_DELETE_AUTOR = ''' + delete from autor where cod_autor in ({}) + and cod_autor not in ({}); + ''' + cursor = exec_legado('update autor set ind_excluido = 0;') cursor = exec_legado(SQL_ENUMERA_REPETIDOS) @@ -281,6 +286,10 @@ def migra_autor(): sql = SQL_UPDATE_PROTOCOLO.format(id_ativo, ids_inativos) exec_legado(sql) + # Faz a exclusão dos autores que não serão migrados + sql = SQL_DELETE_AUTOR.format(ids, id_ativo) + cursor = exec_legado(sql) + def uniformiza_banco(): exec_legado(''' From 24516b9fd4c15bbdaf98ed78f496c81f001b828a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Tue, 21 Nov 2017 15:31:38 -0200 Subject: [PATCH 12/14] Minor Fix --- sapl/legacy/migration.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 140e9836c..60db7d433 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -186,8 +186,8 @@ def migra_autor(): SQL_ENUMERA_REPETIDOS = ''' select cod_parlamentar, COUNT(*) - from autor where col_username is not null - group by col_username, cod_parlamentar + from autor where cod_parlamentar is not null + group by cod_parlamentar having 1 < COUNT(*) order by cod_parlamentar asc; ''' @@ -195,7 +195,8 @@ def migra_autor(): SQL_INFOS_AUTOR = ''' select cod_autor from autor where cod_parlamentar = {} - group by cod_autor; + group by cod_autor + order by col_username, des_cargo desc; ''' SQL_UPDATE_AUTOR = "update autoria set cod_autor = {} where cod_autor in ({});" @@ -233,7 +234,7 @@ def migra_autor(): and cod_autor not in ({}); ''' - cursor = exec_legado('update autor set ind_excluido = 0;') + cursor = exec_legado('update autor set ind_excluido = 0 where cod_autor is not null;') cursor = exec_legado(SQL_ENUMERA_REPETIDOS) autores_parlamentares = [r[0] for r in cursor if r[0]] From 37ca4b8fe3900ace95987a7f99f5449d9e5f5a65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Sconetto?= Date: Tue, 21 Nov 2017 18:06:51 -0200 Subject: [PATCH 13/14] =?UTF-8?q?Adiciona=20a=20migra=C3=A7=C3=A3o=20de=20?= =?UTF-8?q?comiss=C3=B5es?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/migration.py | 110 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 60db7d433..785cb80b9 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -292,6 +292,115 @@ def migra_autor(): cursor = exec_legado(sql) +def migra_comissao(): + SQL_ENUMERA_REPETIDOS = ''' + select cod_comissao, COUNT(*) + from autor where cod_comissao is not null + group by cod_comissao + having 1 < COUNT(*) + order by cod_comissao asc; + ''' + + SQL_INFOS_COMISSAO = ''' + select cod_autor from autor + where cod_comissao = {} + group by cod_autor; + ''' + + SQL_UPDATE_AUTOR = "update autoria set cod_autor = {} where cod_autor in ({});" + + SQL_ENUMERA_AUTORIA_REPETIDOS = ''' + select cod_materia, COUNT(*) from autoria where cod_autor in ({}) + group by cod_materia + having 1 < COUNT(*); + ''' + + SQL_DELETE_AUTORIA = ''' + delete from autoria where cod_materia in ({}) and cod_autor in ({}); + ''' + + SQL_UPDATE_DOCUMENTO_ADMINISTRATIVO = ''' + update documento_administrativo + set cod_autor = {} + where cod_autor in ({}); + ''' + + SQL_UPDATE_PROPOSICAO = ''' + update proposicao + set cod_autor = {} + where cod_autor in ({}); + ''' + + SQL_UPDATE_PROTOCOLO = ''' + update protocolo + set cod_autor = {} + where cod_autor in ({}); + ''' + + SQL_DELETE_AUTOR = ''' + delete from autor where cod_autor in ({}) + and cod_autor not in ({}); + ''' + + cursor = exec_legado('update autor set ind_excluido = 0 where cod_comissao is not null;') + cursor = exec_legado(SQL_ENUMERA_REPETIDOS) + + comissoes_parlamentares = [r[0] for r in cursor if r[0]] + + for cod_comissao in comissoes_parlamentares: + + sql = SQL_INFOS_COMISSAO.format(cod_comissao) + cursor = exec_legado(sql) + + comissoes = [] + + for response in cursor: + comissoes.append(response) + + ids = [c[0] for c in comissoes] + id_ativo, ids_inativos = ids[-1], ids[:-1] + ids = str(ids).strip('[]') + id_ativo = str(id_ativo).strip('[]') + ids_inativos = str(ids_inativos).strip('[]') + + tabelas = ['autoria', 'documento_administrativo', + 'proposicao', 'protocolo'] + + for tabela in tabelas: + if tabela == 'autoria' and id_ativo and ids_inativos: + # Para update e delete no MySQL -> SET SQL_SAFE_UPDATES = 0; + sql = SQL_ENUMERA_AUTORIA_REPETIDOS.format(ids) + cursor = exec_legado(sql) + + materias = [] + for response in cursor: + materias.append(response[0]) + + materias = str(materias).strip('[]') + if materias: + sql = SQL_DELETE_AUTORIA.format(materias, ids_inativos) + exec_legado(sql) + + sql = SQL_UPDATE_AUTOR.format(id_ativo, ids_inativos) + exec_legado(sql) + + elif tabela == 'documento_administrativo' and id_ativo and ids_inativos: + sql = SQL_UPDATE_DOCUMENTO_ADMINISTRATIVO.format(id_ativo, ids_inativos) + exec_legado(sql) + + elif tabela == 'proposicao' and id_ativo and ids_inativos: + sql = SQL_UPDATE_PROPOSICAO.format(id_ativo, ids_inativos) + exec_legado(sql) + + elif tabela == 'protocolo' and id_ativo and ids_inativos: + sql = SQL_UPDATE_PROTOCOLO.format(id_ativo, ids_inativos) + exec_legado(sql) + + # Faz a exclusão dos autores que não serão migrados + sql = SQL_DELETE_AUTOR.format(ids, id_ativo) + cursor = exec_legado(sql) + + def uniformiza_banco(): exec_legado(''' SELECT replace(@@sql_mode,"STRICT_TRANS_TABLES,","ALLOW_INVALID_DATES"); @@ -373,6 +482,7 @@ relatoria | tip_fim_relatoria = NULL | tip_fim_relatoria = 0 exec_legado('UPDATE {} SET {} WHERE {}'.format(*spec)) migra_autor() # Migra autores para um único autor + migra_comissao() # Migra comissões para uma única comissão def iter_sql_records(sql, db): From 7768da56ed88664da7987750f458d1bae2ae5b3c Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Wed, 24 Jan 2018 13:55:42 -0200 Subject: [PATCH 14/14] =?UTF-8?q?Refatora=20unifica=C3=A7=C3=A3o=20de=20au?= =?UTF-8?q?tores=20repetidos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Com alguns testes acrescentados --- sapl/legacy/migration.py | 360 +++++++++++++--------------------- sapl/legacy/scripts/utils.py | 13 ++ sapl/legacy/test_migration.py | 55 ++++++ 3 files changed, 202 insertions(+), 226 deletions(-) create mode 100644 sapl/legacy/test_migration.py diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 785cb80b9..136517e31 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -1,12 +1,12 @@ import re from datetime import date from functools import lru_cache, partial +from itertools import groupby from subprocess import PIPE, call import pkg_resources -import yaml - import reversion +import yaml from django.apps import apps from django.apps.config import AppConfig from django.contrib.auth import get_user_model @@ -16,6 +16,7 @@ from django.core.exceptions import ObjectDoesNotExist from django.db import connections, transaction from django.db.models import Count, Max from django.db.models.base import ModelBase + from sapl.base.models import AppConfig as AppConf from sapl.base.models import (Autor, CasaLegislativa, ProblemaMigracao, TipoAutor) @@ -144,28 +145,32 @@ def exec_sql(sql, db='default'): cursor.execute(sql) return cursor -# UNIFORMIZAÇÃO DO BANCO ANTES DA MIGRAÇÃO ############################### +exec_legado = partial(exec_sql, db='legacy') + + +def primeira_coluna(cursor): + return (r[0] for r in cursor) +# UNIFORMIZAÇÃO DO BANCO ANTES DA MIGRAÇÃO ############################### + SQL_NAO_TEM_TABELA = ''' SELECT count(*) FROM information_schema.columns WHERE table_schema=database() AND TABLE_NAME="{}" ''' -SQL_NAO_TEM_COLUNA = SQL_NAO_TEM_TABELA + ' AND COLUMN_NAME="{}"' - -exec_legado = partial(exec_sql, db='legacy') def existe_tabela_no_legado(tabela): sql = SQL_NAO_TEM_TABELA.format(tabela) - return exec_legado(sql).fetchone()[0] + return primeira_coluna(exec_legado(sql))[0] def existe_coluna_no_legado(tabela, coluna): - sql = SQL_NAO_TEM_COLUNA.format(tabela, coluna) - return exec_legado(sql).fetchone()[0] > 0 + sql_nao_tem_coluna = SQL_NAO_TEM_TABELA + ' AND COLUMN_NAME="{}"' + sql = sql_nao_tem_coluna.format(tabela, coluna) + return primeira_coluna(exec_legado(sql))[0] > 0 def garante_coluna_no_legado(tabela, spec_coluna): @@ -182,223 +187,120 @@ def garante_tabela_no_legado(create_table): assert existe_tabela_no_legado(tabela) -def migra_autor(): - - SQL_ENUMERA_REPETIDOS = ''' - select cod_parlamentar, COUNT(*) - from autor where cod_parlamentar is not null - group by cod_parlamentar - having 1 < COUNT(*) - order by cod_parlamentar asc; - ''' - - SQL_INFOS_AUTOR = ''' - select cod_autor from autor - where cod_parlamentar = {} - group by cod_autor - order by col_username, des_cargo desc; - ''' - - SQL_UPDATE_AUTOR = "update autoria set cod_autor = {} where cod_autor in ({});" - - SQL_ENUMERA_AUTORIA_REPETIDOS = ''' - select cod_materia, COUNT(*) from autoria where cod_autor in ({}) - group by cod_materia - having 1 < COUNT(*); - ''' - - SQL_DELETE_AUTORIA = ''' - delete from autoria where cod_materia in ({}) and cod_autor in ({}); - ''' - - SQL_UPDATE_DOCUMENTO_ADMINISTRATIVO = ''' - update documento_administrativo - set cod_autor = {} - where cod_autor in ({}); - ''' - - SQL_UPDATE_PROPOSICAO = ''' - update proposicao - set cod_autor = {} - where cod_autor in ({}); - ''' - - SQL_UPDATE_PROTOCOLO = ''' - update protocolo - set cod_autor = {} - where cod_autor in ({}); - ''' - - SQL_DELETE_AUTOR = ''' - delete from autor where cod_autor in ({}) - and cod_autor not in ({}); - ''' - - cursor = exec_legado('update autor set ind_excluido = 0 where cod_autor is not null;') - cursor = exec_legado(SQL_ENUMERA_REPETIDOS) - - autores_parlamentares = [r[0] for r in cursor if r[0]] - - for cod_autor in autores_parlamentares: - - sql = SQL_INFOS_AUTOR.format(cod_autor) - - cursor = exec_legado(sql) - autores = [] - - for response in cursor: - autores.append(response) - - ids = [a[0] for a in autores] - id_ativo, ids_inativos = ids[-1], ids[:-1] - ids = str(ids).strip('[]') - id_ativo = str(id_ativo).strip('[]') - ids_inativos = str(ids_inativos).strip('[]') - - tabelas = ['autoria', 'documento_administrativo', - 'proposicao', 'protocolo'] - for tabela in tabelas: - if tabela == 'autoria' and id_ativo and ids_inativos: - # Para update e delete no MySQL -> SET SQL_SAFE_UPDATES = 0; - sql = SQL_ENUMERA_AUTORIA_REPETIDOS.format(ids) - cursor = exec_legado(sql) - - materias = [] - for response in cursor: - materias.append(response[0]) - - materias = str(materias).strip('[]') - if materias: - sql = SQL_DELETE_AUTORIA.format(materias, ids_inativos) - exec_legado(sql) - - sql = SQL_UPDATE_AUTOR.format(id_ativo, ids_inativos) - exec_legado(sql) - - elif tabela == 'documento_administrativo' and id_ativo and ids_inativos: - sql = SQL_UPDATE_DOCUMENTO_ADMINISTRATIVO.format(id_ativo, ids_inativos) - exec_legado(sql) - - elif tabela == 'proposicao' and id_ativo and ids_inativos: - sql = SQL_UPDATE_PROPOSICAO.format(id_ativo, ids_inativos) - exec_legado(sql) - - elif tabela == 'protocolo' and id_ativo and ids_inativos: - sql = SQL_UPDATE_PROTOCOLO.format(id_ativo, ids_inativos) - exec_legado(sql) - - # Faz a exclusão dos autores que não serão migrados - sql = SQL_DELETE_AUTOR.format(ids, id_ativo) - cursor = exec_legado(sql) - - -def migra_comissao(): - SQL_ENUMERA_REPETIDOS = ''' - select cod_comissao, COUNT(*) - from autor where cod_comissao is not null - group by cod_comissao - having 1 < COUNT(*) - order by cod_comissao asc; - ''' - - SQL_INFOS_COMISSAO = ''' - select cod_autor from autor - where cod_comissao = {} - group by cod_autor; - ''' - - SQL_UPDATE_AUTOR = "update autoria set cod_autor = {} where cod_autor in ({});" - - SQL_ENUMERA_AUTORIA_REPETIDOS = ''' - select cod_materia, COUNT(*) from autoria where cod_autor in ({}) - group by cod_materia - having 1 < COUNT(*); - ''' - - SQL_DELETE_AUTORIA = ''' - delete from autoria where cod_materia in ({}) and cod_autor in ({}); - ''' - - SQL_UPDATE_DOCUMENTO_ADMINISTRATIVO = ''' - update documento_administrativo - set cod_autor = {} - where cod_autor in ({}); - ''' - - SQL_UPDATE_PROPOSICAO = ''' - update proposicao - set cod_autor = {} - where cod_autor in ({}); - ''' - - SQL_UPDATE_PROTOCOLO = ''' - update protocolo - set cod_autor = {} - where cod_autor in ({}); - ''' - - SQL_DELETE_AUTOR = ''' - delete from autor where cod_autor in ({}) - and cod_autor not in ({}); - ''' - - cursor = exec_legado('update autor set ind_excluido = 0 where cod_comissao is not null;') - cursor = exec_legado(SQL_ENUMERA_REPETIDOS) - - comissoes_parlamentares = [r[0] for r in cursor if r[0]] - - for cod_comissao in comissoes_parlamentares: - - sql = SQL_INFOS_COMISSAO.format(cod_comissao) - cursor = exec_legado(sql) - - comissoes = [] - - for response in cursor: - comissoes.append(response) - - ids = [c[0] for c in comissoes] - id_ativo, ids_inativos = ids[-1], ids[:-1] - ids = str(ids).strip('[]') - id_ativo = str(id_ativo).strip('[]') - ids_inativos = str(ids_inativos).strip('[]') - - tabelas = ['autoria', 'documento_administrativo', - 'proposicao', 'protocolo'] - - for tabela in tabelas: - if tabela == 'autoria' and id_ativo and ids_inativos: - # Para update e delete no MySQL -> SET SQL_SAFE_UPDATES = 0; - sql = SQL_ENUMERA_AUTORIA_REPETIDOS.format(ids) - cursor = exec_legado(sql) - - materias = [] - for response in cursor: - materias.append(response[0]) - - materias = str(materias).strip('[]') - if materias: - sql = SQL_DELETE_AUTORIA.format(materias, ids_inativos) - exec_legado(sql) - - sql = SQL_UPDATE_AUTOR.format(id_ativo, ids_inativos) - exec_legado(sql) - - elif tabela == 'documento_administrativo' and id_ativo and ids_inativos: - sql = SQL_UPDATE_DOCUMENTO_ADMINISTRATIVO.format(id_ativo, ids_inativos) - exec_legado(sql) - - elif tabela == 'proposicao' and id_ativo and ids_inativos: - sql = SQL_UPDATE_PROPOSICAO.format(id_ativo, ids_inativos) - exec_legado(sql) +TABELAS_REFERENCIANDO_AUTOR = [ + # , + ('autoria', True), + ('documento_administrativo', True), + ('proposicao', True), + ('protocolo', False)] + + +def reverte_exclusao_de_autores_referenciados_no_legado(): + + def get_autores_referenciados(tabela, tem_ind_excluido): + sql = '''select distinct cod_autor from {} + where cod_autor is not null + '''.format(tabela) + if tem_ind_excluido: + sql += ' and ind_excluido != 1' + return primeira_coluna(exec_legado(sql)) + + # reverte exclusões de autores referenciados por outras tabelas + autores_referenciados = { + cod + for tabela, tem_ind_excluido in TABELAS_REFERENCIANDO_AUTOR + for cod in get_autores_referenciados(tabela, tem_ind_excluido)} + exec_legado( + 'update autor set ind_excluido = 0 where cod_autor in {}'.format( + tuple(autores_referenciados) + )) + + +def get_reapontamento_de_autores_repetidos(autores): + """ Dada uma lista ordenada de pares (cod_zzz, cod_autor) retorna: + + * a lista de grupos de cod_autor'es repetidos + (quando há mais de um cod_autor para um mesmo cod_zzz) + + * a lista de cod_autor'es a serem apagados (todos além do 1o de cada grupo) + """ + grupos_de_repetidos = [ + [cod_autor for _, cod_autor in grupo] + for cod_zzz, grupo in groupby(autores, lambda r: r[0])] + # mantém apenas os grupos com mais de um autor por cod_zzz + grupos_de_repetidos = [g for g in grupos_de_repetidos if len(g) > 1] + # aponta cada autor de cada grupo de repetidos para o 1o do seu grupo + reapontamento = {autor: grupo[0] + for grupo in grupos_de_repetidos + for autor in grupo} + # apagaremos todos menos o primeiro + apagar = [k for k, v in reapontamento.items() if k != v] + return reapontamento, apagar + + +def get_autorias_sem_repeticoes(autoria, reapontamento): + "Autorias sem repetições de autores e com ind_primeiro_autor ajustado" + + # substitui cada autor repetido pelo 1o de seu grupo + autoria = sorted((reapontamento[a], m, i) for a, m, i in autoria) + # agrupa por [autor (1o do grupo de repetidos), materia], com + # ind_primeiro_autor == 1 se isso acontece em qualquer autor do grupo + autoria = [(a, m, max(i for a, m, i in grupo)) + for (a, m), grupo in groupby(autoria, lambda x: x[:2])] + return autoria + + +def unifica_autores_repetidos_no_legado(campo_agregador): + "Reúne autores repetidos em um único, antes da migracão" + + # enumeramos a repeticoes segundo o campo relevante + # (p. ex. cod_parlamentar ou cod_comissao) + # a ordenação prioriza, as entradas: + # - não excluidas, + # - em seguida as que têm col_username, + # - em seguida as que têm des_cargo + autores = exec_legado(''' + select {cod_parlamentar}, cod_autor from autor + where {cod_parlamentar} is not null + order by {cod_parlamentar}, + ind_excluido, col_username desc, des_cargo desc'''.format( + cod_parlamentar=campo_agregador)) + + reapontamento, apagar = get_reapontamento_de_autores_repetidos(autores) + + # Reaponta AUTORIA (many-to-many) + + # simplificamos retirando inicialmente as autorias excluidas + exec_legado('delete from autoria where ind_excluido = 1') + + # selecionamos as autorias envolvidas em repetições de autores + from_autoria = ' from autoria where cod_autor in {}'.format( + tuple(reapontamento)) + autoria = exec_legado( + 'select cod_autor, cod_materia, ind_primeiro_autor' + from_autoria) + + # apagamos todas as autorias envolvidas + exec_legado('delete ' + from_autoria) + # e depois inserimos apenas as sem repetições c ind_primeiro_autor ajustado + nova_autoria = get_autorias_sem_repeticoes(autoria, reapontamento) + exec_legado(''' + insert into autoria + (cod_autor, cod_materia, ind_primeiro_autor, ind_excluido) + values {}'''.format(', '.join([str((a, m, i, 0)) + for a, m, i in nova_autoria]))) - elif tabela == 'protocolo' and id_ativo and ids_inativos: - sql = SQL_UPDATE_PROTOCOLO.format(id_ativo, ids_inativos) - exec_legado(sql) + # Reaponta outras tabelas que referenciam autor + for tabela, _ in TABELAS_REFERENCIANDO_AUTOR: + for antigo, novo in reapontamento.items(): + if antigo != novo: + exec_legado(''' + update {} set cod_autor = {} where cod_autor = {} + '''.format(tabela, novo, antigo)) - # Faz a exclusão dos autores que não serão migrados - sql = SQL_DELETE_AUTOR.format(ids, id_ativo) - cursor = exec_legado(sql) + # Finalmente excluimos os autores redundantes, + # cujas referências foram todas substituídas a essa altura + exec_legado('delete from autor where cod_autor in {}'.format( + tuple(apagar))) def uniformiza_banco(): @@ -481,8 +383,14 @@ relatoria | tip_fim_relatoria = NULL | tip_fim_relatoria = 0 spec = spec.split('|') exec_legado('UPDATE {} SET {} WHERE {}'.format(*spec)) - migra_autor() # Migra autores para um único autor - migra_comissao() # Migra comissões para uma única comissão + # retira apontamentos de materia para assunto inexistente + exec_legado('delete from materia_assunto where cod_assunto = 0') + + # corrige string "None" em autor + exec_legado('update autor set des_cargo = NULL where des_cargo = "None"') + + unifica_autores_repetidos_no_legado('cod_parlamentar') + unifica_autores_repetidos_no_legado('cod_comissao') def iter_sql_records(sql, db): diff --git a/sapl/legacy/scripts/utils.py b/sapl/legacy/scripts/utils.py index 6e2e03723..21f74ce52 100644 --- a/sapl/legacy/scripts/utils.py +++ b/sapl/legacy/scripts/utils.py @@ -1,6 +1,19 @@ import inspect +from sapl.base.models import Autor +from sapl.legacy.migration import appconfs + def getsourcelines(model): return [line.rstrip('\n').decode('utf-8') for line in inspect.getsourcelines(model)[0]] + + +def get_models_com_referencia_a_autor(): + + def tem_referencia_a_autor(model): + return any(getattr(field, 'related_model', None) == Autor + for field in model._meta.get_fields()) + + return [model for app in appconfs for model in app.models.values() + if tem_referencia_a_autor(model)] diff --git a/sapl/legacy/test_migration.py b/sapl/legacy/test_migration.py new file mode 100644 index 000000000..a1ae77365 --- /dev/null +++ b/sapl/legacy/test_migration.py @@ -0,0 +1,55 @@ +from random import shuffle + +from .migration import (get_autorias_sem_repeticoes, + get_reapontamento_de_autores_repetidos) + + +def test_unifica_autores_repetidos_no_legado(): + + # cod_parlamentar, cod_autor + autores = [[0, 0], + [1, 10], + [1, 11], + [1, 12], + [2, 20], + [2, 21], + [2, 22], + [3, 30], + [3, 31], + [4, 40], + [5, 50]] + reapontamento, apagar = get_reapontamento_de_autores_repetidos(autores) + assert reapontamento == {10: 10, 11: 10, 12: 10, + 20: 20, 21: 20, 22: 20, + 30: 30, 31: 30} + assert sorted(apagar) == [11, 12, 21, 22, 31] + + # cod_autor, cod_materia, ind_primeiro_autor + autoria = [[10, 111, 0], # não é repetida, mas envolve um autor repetido + + [22, 222, 1], # não é repetida, mas envolve um autor repetido + + [10, 777, 1], # repetição c ind_primeiro_autor==1 no INÍCIO + [10, 777, 0], + [11, 777, 0], + [12, 777, 0], + + [30, 888, 0], # repetição c ind_primeiro_autor==1 no MEIO + [31, 888, 1], + [30, 888, 0], + + [11, 999, 0], # repetição SEM ind_primeiro_autor==1 + [12, 999, 0], + + [21, 999, 0], # repetição SEM ind_primeiro_autor==1 + [22, 999, 0], + ] + shuffle(autoria) # não devemos supor ordem na autoria + nova_autoria = get_autorias_sem_repeticoes(autoria, reapontamento) + assert nova_autoria == sorted([(10, 111, 0), + (20, 222, 1), + (10, 777, 1), + (30, 888, 1), + (10, 999, 0), + (20, 999, 0), + ])