From b9c3bbcfd5902446523f3eb0185874f1d714201c Mon Sep 17 00:00:00 2001 From: Marcio Mazza Date: Thu, 15 Feb 2018 14:41:45 -0200 Subject: [PATCH] =?UTF-8?q?Corrige=20execu=C3=A7=C3=A3o=20condicional=20de?= =?UTF-8?q?=20queries=20pr=C3=A9-migra=C3=A7=C3=A3o?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sapl/legacy/migration.py | 59 +++++++++++++++++++++++------------ sapl/legacy/test_migration.py | 8 ++++- 2 files changed, 46 insertions(+), 21 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index aed35459b..8b7a9e4c1 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -5,9 +5,8 @@ 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 @@ -17,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, ProblemaMigracao, TipoAutor, cria_models_tipo_autor) @@ -149,6 +149,25 @@ def exec_sql(sql, db='default'): exec_legado = partial(exec_sql, db='legacy') +def _formatar_lista_para_sql(iteravel): + lista = list(iteravel) + if lista: + return '({})'.format(str(lista)[1:-1]) # transforma "[...]" em "(...)" + else: + return None + + +def exec_legado_em_subconjunto(sql, ids): + """Executa uma query sql no legado no formato '.... in {}' + interpolando `ids`, se houver ids""" + + lista_sql = _formatar_lista_para_sql(ids) + if lista_sql: + return exec_legado(sql.format(lista_sql)) + else: + return [] + + def primeira_coluna(cursor): return (r[0] for r in cursor) @@ -197,6 +216,8 @@ TABELAS_REFERENCIANDO_AUTOR = [ def reverte_exclusao_de_autores_referenciados_no_legado(): + """Reverte a exclusão de autores que sejam referenciados de alguma forma + na base legada""" def get_autores_referenciados(tabela, tem_ind_excluido): sql = '''select distinct cod_autor from {} @@ -211,10 +232,9 @@ def reverte_exclusao_de_autores_referenciados_no_legado(): 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) - )) + exec_legado_em_subconjunto( + 'update autor set ind_excluido = 0 where cod_autor in {}', + autores_referenciados) def get_reapontamento_de_autores_repetidos(autores): @@ -279,13 +299,13 @@ def unifica_autores_repetidos_no_legado(campo_agregador): 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) + from_autoria = ' from autoria where cod_autor in {}' + autoria = exec_legado_em_subconjunto( + 'select cod_autor, cod_materia, ind_primeiro_autor' + from_autoria, + reapontamento) # apagamos todas as autorias envolvidas - exec_legado('delete ' + from_autoria) + exec_legado_em_subconjunto('delete ' + from_autoria, reapontamento) # e depois inserimos apenas as sem repetições c ind_primeiro_autor ajustado nova_autoria = get_autorias_sem_repeticoes(autoria, reapontamento) exec_legado(''' @@ -304,24 +324,23 @@ def unifica_autores_repetidos_no_legado(campo_agregador): # 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))) + exec_legado_em_subconjunto('delete from autor where cod_autor in {}', + apagar) def anula_tipos_origem_externa_invalidos(): """Anula tipos de origem externa inválidos para que não impeçam a migração da matéria""" - tipos_validos = tuple(primeira_coluna(exec_legado(''' + tipos_validos = primeira_coluna(exec_legado(''' select tip_materia from tipo_materia_legislativa - where ind_excluido <> 1;'''))) + where ind_excluido <> 1;''')) - if tipos_validos: - exec_legado(''' - update materia_legislativa - set tip_origem_externa = NULL - where tip_origem_externa not in {};'''.format(tipos_validos)) + exec_legado_em_subconjunto(''' + update materia_legislativa + set tip_origem_externa = NULL + where tip_origem_externa not in {};''', tipos_validos) def uniformiza_banco(): diff --git a/sapl/legacy/test_migration.py b/sapl/legacy/test_migration.py index a1ae77365..efaa2e6d6 100644 --- a/sapl/legacy/test_migration.py +++ b/sapl/legacy/test_migration.py @@ -1,6 +1,6 @@ from random import shuffle -from .migration import (get_autorias_sem_repeticoes, +from .migration import (_formatar_lista_para_sql, get_autorias_sem_repeticoes, get_reapontamento_de_autores_repetidos) @@ -53,3 +53,9 @@ def test_unifica_autores_repetidos_no_legado(): (10, 999, 0), (20, 999, 0), ]) + + +def test_formatar_lista_para_sql(): + assert _formatar_lista_para_sql([1, 2, 3]) == '(1, 2, 3)' + assert _formatar_lista_para_sql([1]) == '(1)' + assert _formatar_lista_para_sql([]) is None