Browse Source

Remove delete e recria constraints

pull/1477/head
Marcio Mazza 7 years ago
parent
commit
231700f823
  1. 104
      sapl/legacy/migration.py

104
sapl/legacy/migration.py

@ -12,14 +12,13 @@ from django.contrib.auth import get_user_model
from django.contrib.auth.models import Group from django.contrib.auth.models import Group
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.db import ProgrammingError, connections, models, transaction from django.db import connections, transaction
from django.db.models import CharField, Count, Max, TextField from django.db.models import CharField, Count, Max, TextField
from django.db.models.base import ModelBase from django.db.models.base import ModelBase
from model_mommy import mommy from model_mommy import mommy
from model_mommy.mommy import foreign_key_required, make from model_mommy.mommy import foreign_key_required, make
from sapl.base.models import (Argumento, Autor, Constraint, ProblemaMigracao, from sapl.base.models import Autor, ProblemaMigracao, TipoAutor
TipoAutor)
from sapl.comissoes.models import Comissao, Composicao, Participacao from sapl.comissoes.models import Comissao, Composicao, Participacao
from sapl.materia.models import (AcompanhamentoMateria, Proposicao, from sapl.materia.models import (AcompanhamentoMateria, Proposicao,
StatusTramitacao, TipoDocumento, StatusTramitacao, TipoDocumento,
@ -170,44 +169,6 @@ def iter_sql_records(sql, db):
record.__dict__.update(zip(fieldnames, row)) record.__dict__.update(zip(fieldnames, row))
yield record yield record
# Todos os models têm no máximo uma constraint unique together
# Isso é necessário para que o método delete_constraints funcione corretamente
assert all(len(model._meta.unique_together) <= 1
for app in appconfs
for model in app.models.values())
def delete_constraints(model):
# pega nome da unique constraint dado o nome da tabela
table = model._meta.db_table
cursor = exec_sql("SELECT conname FROM pg_constraint WHERE conrelid = "
"(SELECT oid FROM pg_class WHERE relname LIKE "
"'%s') and contype = 'u';" % (table))
result = ()
result = cursor.fetchall()
# se existir um resultado, unique constraint será deletado
for r in result:
if r[0].endswith('key'):
words_list = r[0].split('_')
constraint = Constraint.objects.create(
nome_tabela=table, nome_constraint=r[0],
nome_model=model.__name__, tipo_constraint='one_to_one')
for w in words_list:
Argumento.objects.create(constraint=constraint, argumento=w)
else:
if model._meta.unique_together:
args_list = model._meta.unique_together[0]
constraint = Constraint.objects.create(
nome_tabela=table, nome_constraint=r[0],
nome_model=model.__name__,
tipo_constraint='unique_together')
for a in args_list:
Argumento.objects.create(constraint=constraint,
argumento=a)
warn('Excluindo unique constraint de nome %s' % r[0])
exec_sql("ALTER TABLE %s DROP CONSTRAINT %s;" %
(table, r[0]))
def problema_duplicatas(model, lista_duplicatas, argumentos): def problema_duplicatas(model, lista_duplicatas, argumentos):
for obj in lista_duplicatas: for obj in lista_duplicatas:
@ -228,62 +189,6 @@ def problema_duplicatas(model, lista_duplicatas, argumentos):
reversion.set_comment('%s não é único.' % model.__name__) reversion.set_comment('%s não é único.' % model.__name__)
def recria_constraints():
constraints = Constraint.objects.all()
for con in constraints:
if con.tipo_constraint == 'one_to_one':
nome_tabela = con.nome_tabela
nome_constraint = con.nome_constraint
args = [a.argumento for a in con.argumento_set.all()]
args_string = ''
args_string = "(" + "_".join(map(str, args[2:-1])) + ")"
model = ContentType.objects.filter(
model=con.nome_model.lower())[0].model_class()
try:
exec_sql("ALTER TABLE %s ADD CONSTRAINT %s UNIQUE %s;" %
(nome_tabela, nome_constraint, args_string))
except ProgrammingError:
info('A constraint %s já foi recriada!' % nome_constraint)
if con.tipo_constraint == 'unique_together':
nome_tabela = con.nome_tabela
nome_constraint = con.nome_constraint
# Pegando explicitamente o primeiro valor do filter,
# pois pode ser que haja mais de uma ocorrência
model = ContentType.objects.filter(
model=con.nome_model.lower())[0].model_class()
args = [a.argumento for a in con.argumento_set.all()]
for i in range(len(args)):
if isinstance(model._meta.get_field(args[i]),
models.ForeignKey):
args[i] = args[i] + '_id'
args_string = ''
args_string += "(" + ', '.join(map(str, args)) + ")"
distintos = model.objects.order_by(*args).distinct(*args)
todos = model.objects.all()
if hasattr(model, "content_type"):
distintos = distintos.exclude(content_type_id=None,
object_id=None)
todos = todos.exclude(content_type_id=None, object_id=None)
lista_duplicatas = list(set(todos).difference(set(distintos)))
if lista_duplicatas:
problema_duplicatas(model, lista_duplicatas, args)
else:
try:
exec_sql("ALTER TABLE %s ADD CONSTRAINT %s UNIQUE %s;" %
(nome_tabela, nome_constraint, args_string))
except ProgrammingError:
info('A constraint %s já foi recriada!' % nome_constraint)
except Exception as err:
problema = re.findall('\(.*?\)', err.args[0])
erro('A constraint [%s] da tabela [%s] não pode ser" \
recriada' % (nome_constraint, nome_tabela))
erro('Os dados %s = %s estão duplicados. '
'Arrume antes de recriar as constraints!' %
(problema[0], problema[1]))
# TODO o que é isso? #################################################### # TODO o que é isso? ####################################################
def obj_desnecessario(obj): def obj_desnecessario(obj):
relacoes = [ relacoes = [
@ -484,9 +389,6 @@ class DataMigrator:
while self.delete_stubs(): while self.delete_stubs():
pass pass
info('Recriando constraints...')
recria_constraints()
def _do_migrate(self, obj): def _do_migrate(self, obj):
if isinstance(obj, AppConfig): if isinstance(obj, AppConfig):
models_to_migrate = (model for model in obj.models.values() models_to_migrate = (model for model in obj.models.values()
@ -514,8 +416,6 @@ class DataMigrator:
legacy_model = legacy_app.get_model(legacy_model_name) legacy_model = legacy_app.get_model(legacy_model_name)
legacy_pk_name = legacy_model._meta.pk.name legacy_pk_name = legacy_model._meta.pk.name
delete_constraints(model)
# setup migration strategy for tables with or without a pk # setup migration strategy for tables with or without a pk
if legacy_pk_name == 'id': if legacy_pk_name == 'id':
# There is no pk in the legacy table # There is no pk in the legacy table

Loading…
Cancel
Save