From 5245b34e6a1b938cdb5c15ccda84023e9a52945f Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Fri, 24 Mar 2017 17:07:05 -0300 Subject: [PATCH 1/2] =?UTF-8?q?Corrige=20problema=20da=20exclus=C3=A3o=20d?= =?UTF-8?q?e=20objetos=20protegidos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Luciano Almeida --- sapl/legacy/migration.py | 38 +++++++++++----------- sapl/legacy/scripts/shell_para_migracao.sh | 1 + 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 379ac13ad..1342009b8 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -246,14 +246,12 @@ def recreate_constraints(): unique_constraints.clear() -def stub_desnecessario(obj): +def obj_desnecessario(obj): lista_fields = [ f for f in obj._meta.get_fields() - if (f.one_to_many or f.one_to_one) and f.auto_created - ] - desnecessario = not any( - rr.related_model.objects.filter(**{rr.field.name: obj}).exists() - for rr in lista_fields) + if (f.one_to_many or f.one_to_one) and f.auto_created] + desnecessario = not any(rr.related_model.objects.filter( + **{rr.field.name: obj}).exists() for rr in lista_fields) return desnecessario @@ -424,16 +422,25 @@ class DataMigrator: info('Deletando models com ind_excluido...') while self.to_delete: for obj in self.to_delete: - try: - obj.delete() - self.to_delete.remove(obj) - except ProtectedError: + if obj_desnecessario(obj): + try: + obj.delete() + self.to_delete.remove(obj) + except ProtectedError: + msg = 'A entrada de PK %s da model %s não pode ser ' \ + 'excluida' % (obj.pk, obj._meta.model_name) + descricao = 'Um ou mais objetos protegidos ' + warn(msg + ' => ' + descricao) + save_relation(obj=obj, problema=msg, + descricao=descricao, eh_stub=False) + else: msg = 'A entrada de PK %s da model %s não pode ser ' \ 'excluida' % (obj.pk, obj._meta.model_name) - descricao = 'Um ou mais objetos protegidos ' + descricao = 'Outros objetos dependem dessa entrada' warn(msg + ' => ' + descricao) save_relation(obj=obj, problema=msg, descricao=descricao, eh_stub=False) + self.to_delete.remove(obj) info('Deletando stubs desnecessários...') while self.delete_stubs(): @@ -468,13 +475,6 @@ class DataMigrator: legacy_model = legacy_app.get_model(legacy_model_name) legacy_pk_name = legacy_model._meta.pk.name - # Clear all model entries - # They may have been created in a previous migration attempt - try: - model.objects.all().delete() - except ProtectedError: - Proposicao.objects.all().delete() - model.objects.all().delete() delete_constraints(model) # setup migration strategy for tables with or without a pk @@ -520,7 +520,7 @@ class DataMigrator: if obj.content_object and obj.eh_stub: original = obj.content_type.get_all_objects_for_this_type( id=obj.object_id) - if stub_desnecessario(original[0]): + if obj_desnecessario(original[0]): qtd_exclusoes, *_ = original.delete() assert qtd_exclusoes == 1 qtd_exclusoes, *_ = obj.delete() diff --git a/sapl/legacy/scripts/shell_para_migracao.sh b/sapl/legacy/scripts/shell_para_migracao.sh index fb0f3c6de..5f5ea97b7 100755 --- a/sapl/legacy/scripts/shell_para_migracao.sh +++ b/sapl/legacy/scripts/shell_para_migracao.sh @@ -5,4 +5,5 @@ # Rode esse script a partir da raiz do projeto +DATABASE_NAME=$1 ./manage.py migrate --settings sapl.legacy_migration_settings DATABASE_NAME=$1 ./manage.py shell_plus --settings sapl.legacy_migration_settings From a0042b1700f85c83ffa3dd29b77b09f3ba4295d3 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Wed, 29 Mar 2017 16:32:56 -0300 Subject: [PATCH 2/2] =?UTF-8?q?Arruma=20loop=20infinto=20na=20prote=C3=A7?= =?UTF-8?q?=C3=A3o=20contra=20exclus=C3=A3o.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Luciano Almeida --- sapl/legacy/migration.py | 66 +++++++++++----------- sapl/legacy/scripts/fix_tables.sql | 4 +- sapl/legacy/scripts/shell_para_migracao.sh | 1 - 3 files changed, 34 insertions(+), 37 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 1342009b8..5b326897f 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -26,7 +26,7 @@ from sapl.norma.models import (AssuntoNorma, NormaJuridica, TipoVinculoNormaJuridica) from sapl.parlamentares.models import Parlamentar from sapl.protocoloadm.models import Protocolo, StatusTramitacaoAdministrativo -from sapl.sessao.models import ExpedienteMateria, OrdemDia, SessaoPlenaria +from sapl.sessao.models import ExpedienteMateria, OrdemDia from sapl.settings import PROJECT_DIR from sapl.utils import normalize @@ -247,12 +247,12 @@ def recreate_constraints(): def obj_desnecessario(obj): - lista_fields = [ + relacoes = [ f for f in obj._meta.get_fields() if (f.one_to_many or f.one_to_one) and f.auto_created] - desnecessario = not any(rr.related_model.objects.filter( - **{rr.field.name: obj}).exists() for rr in lista_fields) - return desnecessario + sem_referencia = not any(rr.related_model.objects.filter( + **{rr.field.name: obj}).exists() for rr in relacoes) + return sem_referencia def get_last_value(model): @@ -413,34 +413,23 @@ class DataMigrator: return 0 info('Excluindo entradas antigas do banco.') call([PROJECT_DIR.child('manage.py'), 'flush', - '--settings=sapl.settings', '--database=default', '--no-input'], - stdout=PIPE) + '--database=default', '--no-input'], stdout=PIPE) info('Começando migração: %s...' % obj) self._do_migrate(obj) - # exclude logically deleted in legacy base + + # Itera várias vezes na lista excluindo o que for possível info('Deletando models com ind_excluido...') - while self.to_delete: - for obj in self.to_delete: - if obj_desnecessario(obj): - try: - obj.delete() - self.to_delete.remove(obj) - except ProtectedError: - msg = 'A entrada de PK %s da model %s não pode ser ' \ - 'excluida' % (obj.pk, obj._meta.model_name) - descricao = 'Um ou mais objetos protegidos ' - warn(msg + ' => ' + descricao) - save_relation(obj=obj, problema=msg, - descricao=descricao, eh_stub=False) - else: - msg = 'A entrada de PK %s da model %s não pode ser ' \ - 'excluida' % (obj.pk, obj._meta.model_name) - descricao = 'Outros objetos dependem dessa entrada' - warn(msg + ' => ' + descricao) - save_relation(obj=obj, problema=msg, - descricao=descricao, eh_stub=False) - self.to_delete.remove(obj) + while self.delete_ind_excluido(): + pass + # Salva o que não pôde ser excluido da lista no problema da migração + for obj in self.to_delete: + msg = 'A entrada de PK %s da model %s não pode ser ' \ + 'excluida' % (obj.pk, obj._meta.model_name) + descricao = 'Um ou mais objetos protegidos ' + warn(msg + ' => ' + descricao) + save_relation(obj=obj, problema=msg, + descricao=descricao, eh_stub=False) info('Deletando stubs desnecessários...') while self.delete_stubs(): @@ -514,6 +503,20 @@ class DataMigrator: if getattr(old, 'ind_excluido', False): self.to_delete.append(new) + def delete_ind_excluido(self): + excluidos = 0 + for obj in self.to_delete: + if obj_desnecessario(obj): + try: + obj.delete() + except ProtectedError: + pass + else: + self.to_delete.remove(obj) + excluidos += 1 + + return excluidos + def delete_stubs(self): excluidos = 0 for obj in ProblemaMigracao.objects.all(): @@ -589,10 +592,6 @@ def adjust_protocolo(new, old): new.numero = p['numero__max'] + 1 -def adjust_sessaoplenaria(new, old): - assert not old.tip_expediente - - def adjust_tipoproposicao(new, old): if old.ind_mat_ou_doc == 'M': new.tipo_conteudo_related = TipoMateriaLegislativa.objects.get( @@ -689,7 +688,6 @@ AJUSTE_ANTES_SALVAR = { Parlamentar: adjust_parlamentar, Participacao: adjust_participacao, Protocolo: adjust_protocolo, - SessaoPlenaria: adjust_sessaoplenaria, TipoProposicao: adjust_tipoproposicao, StatusTramitacao: adjust_statustramitacao, StatusTramitacaoAdministrativo: adjust_statustramitacaoadm, diff --git a/sapl/legacy/scripts/fix_tables.sql b/sapl/legacy/scripts/fix_tables.sql index a112775b5..479a2ed5e 100644 --- a/sapl/legacy/scripts/fix_tables.sql +++ b/sapl/legacy/scripts/fix_tables.sql @@ -1,5 +1,5 @@ -- Apaga as restrições somente para essa sessão -SET SESSION sql_mode = ''; +SELECT REPLACE(@@sql_mode,'STRICT_TRANS_TABLES,',''); -- Exclui procedures caso já existam DROP PROCEDURE IF EXISTS verifica_campos_proposicao; DROP PROCEDURE IF EXISTS verifica_campos_sessao_plenaria_presenca; @@ -9,7 +9,7 @@ CREATE PROCEDURE verifica_campos_proposicao() BEGIN IF NOT EXISTS (SELECT * FROM -- Procedure para criar campos cod_presenca_sessao (sendo a nova PK da tabela) e dat_sessao em sessao_plenaria_presenca CREATE PROCEDURE verifica_campos_sessao_plenaria_presenca() BEGIN IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='sessao_plenaria_presenca' AND column_name='cod_presenca_sessao') THEN ALTER TABLE sessao_plenaria_presenca DROP PRIMARY KEY, ADD cod_presenca_sessao INT AUTO_INCREMENT PRIMARY KEY FIRST; END IF; IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='sessao_plenaria_presenca' AND column_name='dat_sessao') THEN ALTER TABLE sessao_plenaria_presenca ADD COLUMN dat_sessao DATE NULL after cod_parlamentar; END IF; END; -- Procedure para criar tabela lexml_registro_provedor e lexml_registro_publicador -CREATE PROCEDURE cria_lexml_registro_provedor_e_publicador() BEGIN CREATE TABLE IF NOT EXISTS lexml_registro_publicador (cod_publicador INT AUTO_INCREMENT NOT NULL, id_publicador INT, nom_publicador VARCHAR(255), adm_email VARCHAR(50), sigla VARCHAR(255), nom_responsavel VARCHAR(255), tipo VARCHAR(50), id_responsavel INT, PRIMARY KEY (cod_publicador)); CREATE TABLE IF NOT EXISTS lexml_registro_provedor (cod_provedor INT AUTO_INCREMENT NOT NULL, id_provedor INT, nom_provedor VARCHAR(255), sgl_provedor VARCHAR(15), adm_email VARCHAR(50), nom_responsavel VARCHAR(255), tipo VARCHAR(50), id_responsavel INT, xml_provedor LONGTEXT, PRIMARY KEY (cod_provedor)); END; +CREATE PROCEDURE cria_lexml_registro_provedor_e_publicador() BEGIN IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='lexml_registro_publicador') THEN CREATE TABLE lexml_registro_publicador (cod_publicador INT AUTO_INCREMENT NOT NULL, id_publicador INT, nom_publicador VARCHAR(255), adm_email VARCHAR(50), sigla VARCHAR(255), nom_responsavel VARCHAR(255), tipo VARCHAR(50), id_responsavel INT, PRIMARY KEY (cod_publicador)); END IF; IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='lexml_registro_provedor') THEN CREATE TABLE lexml_registro_provedor (cod_provedor INT AUTO_INCREMENT NOT NULL, id_provedor INT, nom_provedor VARCHAR(255), sgl_provedor VARCHAR(15), adm_email VARCHAR(50), nom_responsavel VARCHAR(255), tipo VARCHAR(50), id_responsavel INT, xml_provedor LONGTEXT, PRIMARY KEY (cod_provedor)); END IF; END; -- Executa as procedures criadas acima CALL verifica_campos_proposicao; CALL verifica_campos_sessao_plenaria_presenca; diff --git a/sapl/legacy/scripts/shell_para_migracao.sh b/sapl/legacy/scripts/shell_para_migracao.sh index 5f5ea97b7..fb0f3c6de 100755 --- a/sapl/legacy/scripts/shell_para_migracao.sh +++ b/sapl/legacy/scripts/shell_para_migracao.sh @@ -5,5 +5,4 @@ # Rode esse script a partir da raiz do projeto -DATABASE_NAME=$1 ./manage.py migrate --settings sapl.legacy_migration_settings DATABASE_NAME=$1 ./manage.py shell_plus --settings sapl.legacy_migration_settings