Browse Source

Merge pull request #883 from interlegis/828-objeto-inexistente

fix #828 objeto inexistente
pull/892/head
Luciano Henrique Nunes de Almeida 8 years ago
committed by GitHub
parent
commit
2fb975bb26
  1. 77
      sapl/legacy/migration.py
  2. 3
      sapl/legacy/scripts/fix_tables.sql
  3. 2
      sapl/legacy_migration_settings.py
  4. 2
      sapl/norma/forms.py

77
sapl/legacy/migration.py

@ -6,8 +6,8 @@ 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.models import CharField, TextField, ProtectedError
from django.db import connections, models, OperationalError, ProgrammingError
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]
@ -115,8 +117,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 +148,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)
@ -217,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()
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)
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))
def save_with_id(new, id):
last_value = get_last_value(type(new))
alter_sequence(type(new), id)
new.save()
alter_sequence(type(new), last_value + 1)
assert new.id == id, 'New id is different from provided!'
@ -241,7 +262,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 +353,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)
@ -355,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):
@ -485,6 +507,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
@ -533,6 +567,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)
@ -557,6 +600,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,
@ -566,6 +610,7 @@ AJUSTE_ANTES_SALVAR = {
AJUSTE_DEPOIS_SALVAR = {
NormaJuridica: adjust_normajuridica_depois_salvar,
Protocolo: adjust_protocolo_depois_salvar,
}
# CHECKS ####################################################################
@ -586,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'

3
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;

2
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'
}

2
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: {

Loading…
Cancel
Save