django-cities-light
django-cities-light copied to clipboard
'display_name' and 'name' fields are the same size
Hello,
Currently, if I try to create a City with a name of 200 characters (the max_length for this field), there is an exception raised on creation (DataError). Example :
country = Country.objects.get(code2='FR')
city_name = 'a' * 200
city = City(country=self.country, name=city_name)
city.save() # DataError: value too long for type character varying(200)
It seems to be because display_name
and name
fields have the same max_length (200), and the display_name
consists of the name + the country name. Is there a way to avoid this problem ?
Best regards
Thanks for your feedback !
Could you post the full traceback please ?
Here's the full error:
In [3]: city = City(country=country, name='a' * 250)
In [4]: city.save()
---------------------------------------------------------------------------
DataError Traceback (most recent call last)
/root/.local/lib/python3.4/site-packages/django/db/backends/utils.py in execute(self, sql, params)
63 else:
---> 64 return self.cursor.execute(sql, params)
65
DataError: value too long for type character varying(200)
The above exception was the direct cause of the following exception:
DataError Traceback (most recent call last)
<ipython-input-4-1ed4f2ba6510> in <module>()
----> 1 city.save()
/root/.local/lib/python3.4/site-packages/django/db/models/base.py in save(self, force_insert, force_update, using, update_fields)
706
707 self.save_base(using=using, force_insert=force_insert,
--> 708 force_update=force_update, update_fields=update_fields)
709 save.alters_data = True
710
/root/.local/lib/python3.4/site-packages/django/db/models/base.py in save_base(self, raw, force_insert, force_update, using, update_fields)
734 if not raw:
735 self._save_parents(cls, using, update_fields)
--> 736 updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
737 # Store the database on which the object was saved
738 self._state.db = using
/root/.local/lib/python3.4/site-packages/django/db/models/base.py in _save_table(self, raw, cls, force_insert, force_update, using, update_fields)
818
819 update_pk = bool(meta.has_auto_field and not pk_set)
--> 820 result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
821 if update_pk:
822 setattr(self, meta.pk.attname, result)
/root/.local/lib/python3.4/site-packages/django/db/models/base.py in _do_insert(self, manager, using, fields, update_pk, raw)
857 """
858 return manager._insert([self], fields=fields, return_id=update_pk,
--> 859 using=using, raw=raw)
860
861 def delete(self, using=None, keep_parents=False):
/root/.local/lib/python3.4/site-packages/django/db/models/manager.py in manager_method(self, *args, **kwargs)
120 def create_method(name, method):
121 def manager_method(self, *args, **kwargs):
--> 122 return getattr(self.get_queryset(), name)(*args, **kwargs)
123 manager_method.__name__ = method.__name__
124 manager_method.__doc__ = method.__doc__
/root/.local/lib/python3.4/site-packages/django/db/models/query.py in _insert(self, objs, fields, return_id, raw, using)
1037 query = sql.InsertQuery(self.model)
1038 query.insert_values(fields, objs, raw=raw)
-> 1039 return query.get_compiler(using=using).execute_sql(return_id)
1040 _insert.alters_data = True
1041 _insert.queryset_only = False
/root/.local/lib/python3.4/site-packages/django/db/models/sql/compiler.py in execute_sql(self, return_id)
1058 with self.connection.cursor() as cursor:
1059 for sql, params in self.as_sql():
-> 1060 cursor.execute(sql, params)
1061 if not (return_id and cursor):
1062 return
/root/.local/lib/python3.4/site-packages/django/db/backends/utils.py in execute(self, sql, params)
77 start = time()
78 try:
---> 79 return super(CursorDebugWrapper, self).execute(sql, params)
80 finally:
81 stop = time()
/root/.local/lib/python3.4/site-packages/django/db/backends/utils.py in execute(self, sql, params)
62 return self.cursor.execute(sql)
63 else:
---> 64 return self.cursor.execute(sql, params)
65
66 def executemany(self, sql, param_list):
/root/.local/lib/python3.4/site-packages/django/db/utils.py in __exit__(self, exc_type, exc_value, traceback)
93 if dj_exc_type not in (DataError, IntegrityError):
94 self.wrapper.errors_occurred = True
---> 95 six.reraise(dj_exc_type, dj_exc_value, traceback)
96
97 def __call__(self, func):
/root/.local/lib/python3.4/site-packages/django/utils/six.py in reraise(tp, value, tb)
683 value = tp()
684 if value.__traceback__ is not tb:
--> 685 raise value.with_traceback(tb)
686 raise value
687
/root/.local/lib/python3.4/site-packages/django/db/backends/utils.py in execute(self, sql, params)
62 return self.cursor.execute(sql)
63 else:
---> 64 return self.cursor.execute(sql, params)
65
66 def executemany(self, sql, param_list):
DataError: value too long for type character varying(200)
Thanks a lot for your feedback ! This is very interresting, note that your example code works fine here:
In [1]: from cities_light.models import City, Country
In [2]: country = Country.objects.get(code2='FR')
In [3]: city_name = 'b' * 200
In [4]: city = City(country=country, name=city_name)
In [5]: city.save()
/home/jpic/env/lib/python2.7/site-packages/autoslug/utils.py:31: RuntimeWarning: Argument <type 'str'> is not an unicode object. Passing an encoded string will likely have unexpected results.
return django_slugify(unidecode(value))
In [6]: City.objects.get(name=city_name).name
Out[6]: u'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'
In [7]: City.objects.get(name=city_name).pk
Out[7]: 23223
In your example, 'a' * 250
is used.
Could you please re-explain what the problem exactly is here ?
Thanks !!
Note that I have nothing against incrementing the size of this column, if we have an actual use case.
Hello,
Sorry for the delay. I have been doing a lot of tests, and I can't reproduce the bug with a fresh install of django (with python 2 or python 3). It seems the bug comes from my code, or a migration I wrote. I'll get back to you when I know more about this.
Thank you, Best regards
I ran into this issue while using model-mommy to generate fixtures for unit testing.
The default Region and City have a pre_save signal that generates the display_name by concatenating the Region+County names, and the City+Region+Country names, respectively.
If using max lengths, it results in 400 and 600 chars, way over the max 200.
django.db.utils.DataError: value too long for type character varying(200)