From bc0afcbd96b91b556a97a954d845bff6a271cb74 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Thu, 15 Dec 2016 11:51:27 -0200 Subject: [PATCH 1/3] Arruma problema do objeto inexistente Signed-off-by: Luciano Almeida --- sapl/legacy/migration.py | 27 ++++++++++++++++++++++----- sapl/legacy/scripts/fix_tables.sql | 3 +++ sapl/legacy_migration_settings.py | 2 ++ sapl/norma/forms.py | 2 -- 4 files changed, 27 insertions(+), 7 deletions(-) create mode 100644 sapl/legacy/scripts/fix_tables.sql diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index ffe48cd9a..5b1797715 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -6,7 +6,7 @@ from django.apps import apps from django.apps.config import AppConfig from django.contrib.auth import get_user_model from django.core.exceptions import ObjectDoesNotExist -from django.db import connections, models +from django.db import connections, models, OperationalError, ProgrammingError from django.db.models import CharField, TextField, ProtectedError from django.db.models.base import ModelBase from model_mommy import mommy @@ -115,8 +115,13 @@ def get_fk_related(field, value, label=None): if value == 0: if not field.null: fields_dict = get_fields_dict(field.related_model) - value = mommy.make(field.related_model, - **fields_dict) + # Cria stub ao final da tabela para evitar erros + pk = 1 + if hasattr(field.related_model.objects.last(), 'pk'): + pk = field.related_model.objects.last().pk + value = mommy.make( + field.related_model, **fields_dict, + pk=(pk + 1 or 1)) descricao = 'stub criado para campos não nuláveis!' save_relation(value, [field.name], msg, descricao, eh_stub=True) @@ -141,6 +146,15 @@ def get_field(model, fieldname): return model._meta.get_field(fieldname) +def exec_sql_file(path, db='default'): + cursor = connections[db].cursor() + for line in open(path): + try: + cursor.execute(line) + except (OperationalError, ProgrammingError) as e: + print("Args: '%s'" % (str(e.args))) + + def exec_sql(sql, db='default'): cursor = connections[db].cursor() cursor.execute(sql) @@ -221,11 +235,13 @@ def save_with_id(new, id): sequence_name = '%s_id_seq' % type(new)._meta.db_table cursor = exec_sql('SELECT last_value from %s;' % sequence_name) (last_value,) = cursor.fetchone() + if last_value == 1 or id != last_value + 1: # we explicitly set the next id if last_value == 1 # because last_value == 1 for a table containing either 0 or 1 records # (we would have trouble for id == 2 and a missing id == 1) - exec_sql('ALTER SEQUENCE %s RESTART WITH %s;' % (sequence_name, id)) + cursor = exec_sql( + 'ALTER SEQUENCE %s RESTART WITH %s;' % (sequence_name, id)) new.save() assert new.id == id, 'New id is different from provided!' @@ -241,7 +257,7 @@ def save_relation(obj, nome_campo='', problema='', descricao='', def make_stub(model, id): fields_dict = get_fields_dict(model) - new = mommy.prepare(model, **fields_dict) + new = mommy.prepare(model, **fields_dict, pk=id) save_with_id(new, id) return new @@ -332,6 +348,7 @@ class DataMigrator: # warning: model/app migration order is of utmost importance self.to_delete = [] ProblemaMigracao.objects.all().delete() + exec_sql_file('sapl/legacy/scripts/fix_tables.sql', 'legacy') get_user_model().objects.exclude(is_superuser=True).delete() info('Começando migração: %s...' % obj) diff --git a/sapl/legacy/scripts/fix_tables.sql b/sapl/legacy/scripts/fix_tables.sql new file mode 100644 index 000000000..997379f65 --- /dev/null +++ b/sapl/legacy/scripts/fix_tables.sql @@ -0,0 +1,3 @@ +DROP PROCEDURE IF EXISTS verifica_campos; +CREATE PROCEDURE verifica_campos() BEGIN IF NOT EXISTS (SELECT * FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='proposicao' AND column_name='num_proposicao') THEN ALTER TABLE proposicao add column num_proposicao int(11) NULL after txt_justif_devolucao; END IF; END; +CALL verifica_campos; diff --git a/sapl/legacy_migration_settings.py b/sapl/legacy_migration_settings.py index 0aab3baa9..4176c6df9 100644 --- a/sapl/legacy_migration_settings.py +++ b/sapl/legacy_migration_settings.py @@ -28,6 +28,8 @@ DATABASES['legacy'] = config('DATABASE_URL', cast=db_url,) DATABASE_ROUTERS = ['sapl.legacy.router.LegacyRouter', ] +DEBUG = False + MOMMY_CUSTOM_FIELDS_GEN = { 'django.db.models.ForeignKey': 'sapl.legacy.migration.make_with_log' } diff --git a/sapl/norma/forms.py b/sapl/norma/forms.py index 68b059436..02420adab 100644 --- a/sapl/norma/forms.py +++ b/sapl/norma/forms.py @@ -35,8 +35,6 @@ ORDENACAO_CHOICES = [('', '---------'), class NormaFilterSet(django_filters.FilterSet): - RANGE_ANOS.insert(0, ('', 'Selecione')) - filter_overrides = {models.DateField: { 'filter_class': django_filters.DateFromToRangeFilter, 'extra': lambda f: { From ab0724d6e3226f3879590767c941c30f390fbdfc Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Thu, 29 Dec 2016 15:43:22 -0200 Subject: [PATCH 2/3] =?UTF-8?q?Arruma=20numero=20protocolo=20nulo=20e=20fu?= =?UTF-8?q?n=C3=A7=C3=A3o=20save=5Fwith=5Fid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Luciano Almeida --- sapl/legacy/migration.py | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index 5b1797715..d8ce30175 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -7,7 +7,7 @@ from django.apps.config import AppConfig from django.contrib.auth import get_user_model from django.core.exceptions import ObjectDoesNotExist from django.db import connections, models, OperationalError, ProgrammingError -from django.db.models import CharField, TextField, ProtectedError +from django.db.models import CharField, TextField, ProtectedError, Max from django.db.models.base import ModelBase from model_mommy import mommy from model_mommy.mommy import foreign_key_required, make @@ -17,9 +17,10 @@ from sapl.comissoes.models import Comissao, Composicao, Participacao from sapl.materia.models import (Proposicao, StatusTramitacao, TipoDocumento, TipoMateriaLegislativa, TipoProposicao, Tramitacao) +from sapl.legacy.models import Protocolo as ProtocoloLegado from sapl.norma.models import AssuntoNorma, NormaJuridica from sapl.parlamentares.models import Parlamentar -from sapl.protocoloadm.models import StatusTramitacaoAdministrativo +from sapl.protocoloadm.models import Protocolo, StatusTramitacaoAdministrativo from sapl.sessao.models import ExpedienteMateria, OrdemDia, SessaoPlenaria from sapl.utils import normalize @@ -37,6 +38,7 @@ appconfs = [apps.get_app_config(n) for n in [ unique_constraints = [] one_to_one_constraints = [] +primeira_vez = [] name_sets = [set(m.__name__ for m in ac.get_models()) for ac in appconfs] @@ -236,13 +238,11 @@ def save_with_id(new, id): cursor = exec_sql('SELECT last_value from %s;' % sequence_name) (last_value,) = cursor.fetchone() - if last_value == 1 or id != last_value + 1: - # we explicitly set the next id if last_value == 1 - # because last_value == 1 for a table containing either 0 or 1 records - # (we would have trouble for id == 2 and a missing id == 1) - cursor = exec_sql( - 'ALTER SEQUENCE %s RESTART WITH %s;' % (sequence_name, id)) + cursor = exec_sql( + 'ALTER SEQUENCE %s RESTART WITH %s;' % (sequence_name, id)) new.save() + cursor = exec_sql( + 'ALTER SEQUENCE %s RESTART WITH %s;' % (sequence_name, last_value + 1)) assert new.id == id, 'New id is different from provided!' @@ -502,6 +502,18 @@ def adjust_participacao(new, old): new.composicao = composicao +def adjust_protocolo(new, old): + if new.numero is None and not primeira_vez: + p = ProtocoloLegado.objects.filter( + ano_protocolo=new.ano).aggregate(Max('num_protocolo')) + new.numero = p['num_protocolo__max'] + 1 + primeira_vez.append(True) + if new.numero is None and primeira_vez: + p = Protocolo.objects.filter( + ano=new.ano).aggregate(Max('numero')) + new.numero = p['numero__max'] + 1 + + def adjust_sessaoplenaria(new, old): assert not old.tip_expediente @@ -550,6 +562,15 @@ def adjust_normajuridica_depois_salvar(new, old): new.assuntos.add(AssuntoNorma.objects.get(pk=pk_assunto)) +def adjust_protocolo_depois_salvar(new, old): + if old.num_protocolo is None: + problema = 'Número do protocolo de PK %s é nulo' % new.pk + descricao = 'Número do protocolo alterado para %s!' % new.numero + warn(problema + ' => ' + descricao) + save_relation(obj=new, problema=problema, + descricao=descricao, eh_stub=False) + + def adjust_autor(new, old): if old.cod_parlamentar: new.autor_related = Parlamentar.objects.get(pk=old.cod_parlamentar) @@ -574,6 +595,7 @@ AJUSTE_ANTES_SALVAR = { OrdemDia: adjust_ordemdia, Parlamentar: adjust_parlamentar, Participacao: adjust_participacao, + Protocolo: adjust_protocolo, SessaoPlenaria: adjust_sessaoplenaria, TipoProposicao: adjust_tipoproposicao, StatusTramitacao: adjust_statustramitacao, @@ -583,6 +605,7 @@ AJUSTE_ANTES_SALVAR = { AJUSTE_DEPOIS_SALVAR = { NormaJuridica: adjust_normajuridica_depois_salvar, + Protocolo: adjust_protocolo_depois_salvar, } # CHECKS #################################################################### From edf6ed4113244d9a30c0dda605ac2ee0bc357202 Mon Sep 17 00:00:00 2001 From: Luciano Almeida Date: Thu, 5 Jan 2017 16:46:21 -0200 Subject: [PATCH 3/3] =?UTF-8?q?Arruma=20fun=C3=A7=C3=A3o=20save=5Fwith=5Fi?= =?UTF-8?q?d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Luciano Almeida --- sapl/legacy/migration.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/sapl/legacy/migration.py b/sapl/legacy/migration.py index d8ce30175..a46696700 100644 --- a/sapl/legacy/migration.py +++ b/sapl/legacy/migration.py @@ -233,16 +233,21 @@ def stub_desnecessario(obj): return desnecessario -def save_with_id(new, id): - sequence_name = '%s_id_seq' % type(new)._meta.db_table - cursor = exec_sql('SELECT last_value from %s;' % sequence_name) - (last_value,) = cursor.fetchone() +def get_last_value(model): + last_value = model.objects.all().aggregate(Max('pk')) + return last_value['pk__max'] if last_value['pk__max'] else 0 + + +def alter_sequence(model, id): + sequence_name = '%s_id_seq' % model._meta.db_table + exec_sql('ALTER SEQUENCE %s RESTART WITH %s;' % (sequence_name, id)) - cursor = exec_sql( - 'ALTER SEQUENCE %s RESTART WITH %s;' % (sequence_name, id)) + +def save_with_id(new, id): + last_value = get_last_value(type(new)) + alter_sequence(type(new), id) new.save() - cursor = exec_sql( - 'ALTER SEQUENCE %s RESTART WITH %s;' % (sequence_name, last_value + 1)) + alter_sequence(type(new), last_value + 1) assert new.id == id, 'New id is different from provided!' @@ -372,7 +377,7 @@ class DataMigrator: while self.delete_stubs(): pass info('Recriando unique constraints...') - recreate_constraints() + # recreate_constraints() def _do_migrate(self, obj): if isinstance(obj, AppConfig): @@ -626,6 +631,8 @@ def check_app_no_ind_excluido(app): def make_with_log(model, _quantity=None, make_m2m=False, **attrs): + last_value = get_last_value(model) + alter_sequence(model, last_value + 1) fields_dict = get_fields_dict(model) stub = make(model, _quantity, make_m2m, **fields_dict) problema = 'Um stub foi necessário durante a criação de um outro stub'