Explicitly handle too-long field values

If you use a traditional database engine (such as MySQL/MariaDB) then
maximum character field lengths are enforced, however depending on the
configuration this may result in an exception rather than a warning and
truncation and will also break the per-layer transaction. To avoid that
ugliness, add a signal handler to do it internally, which as a bonus
lets us know if field lenghts are too short for data when using database
engines that don't enforce lengths (e.g. SQLite).

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
This commit is contained in:
Paul Eggleton 2018-01-04 17:38:34 +13:00
parent 87fe124ad7
commit bc26b95d0b

View File

@ -9,10 +9,31 @@ from datetime import datetime
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.core.validators import URLValidator from django.core.validators import URLValidator
from django.db.models.signals import pre_save
from django.dispatch import receiver
import os.path import os.path
import re import re
import posixpath import posixpath
from . import utils
logger = utils.logger_create('LayerIndexModels')
@receiver(pre_save)
def truncate_charfield_values(sender, instance, *args, **kwargs):
# Instead of leaving this up to the database, check and handle it
# ourselves to avoid nasty exceptions; as a bonus we won't miss when
# the max length is too short with databases that don't enforce
# the limits (e.g. sqlite)
for field in instance._meta.get_fields():
if isinstance(field, models.CharField):
value = getattr(instance, field.name)
if value and len(value) > field.max_length:
logger.warning('%s.%s: length %s exceeds maximum (%s), truncating' % (instance.__class__.__name__, field.name, len(value), field.max_length))
setattr(instance, field.name, value[:field.max_length])
class PythonEnvironment(models.Model): class PythonEnvironment(models.Model):
name = models.CharField(max_length=50) name = models.CharField(max_length=50)