DataError: value too long for type character varying(24) when trying to fetch point of sales
Alvezgr opened this issue · 4 comments
Hi, I recently came across an issue when trying to fetch point of sales from a given taxpayer.
I'm using
django=3.2.13
python=3.10.4
postgresql=14
When I run taxpayer.fetch_point_of_sales()
an exception occurs.
The traceback is the following:
---------------------------------------------------------------------------
DoesNotExist Traceback (most recent call last)
File /usr/local/lib/python3.10/site-packages/django/db/models/query.py:581, in QuerySet.get_or_create(self, defaults, **kwargs)
580 try:
--> 581 return self.get(**kwargs), False
582 except self.model.DoesNotExist:
File /usr/local/lib/python3.10/site-packages/django/db/models/query.py:435, in QuerySet.get(self, *args, **kwargs)
434 if not num:
--> 435 raise self.model.DoesNotExist(
436 "%s matching query does not exist." %
437 self.model._meta.object_name
438 )
439 raise self.model.MultipleObjectsReturned(
440 'get() returned more than one %s -- it returned %s!' % (
441 self.model._meta.object_name,
442 num if not limit or num < limit else 'more than %s' % (limit - 1),
443 )
444 )
DoesNotExist: PointOfSales matching query does not exist.
During handling of the above exception, another exception occurred:
StringDataRightTruncation Traceback (most recent call last)
File /usr/local/lib/python3.10/site-packages/django/db/backends/utils.py:84, in CursorWrapper._execute(self, sql, params, *ignored_wrapper_args)
83 else:
---> 84 return self.cursor.execute(sql, params)
StringDataRightTruncation: value too long for type character varying(24)
The above exception was the direct cause of the following exception:
DataError Traceback (most recent call last)
Input In [34], in <cell line: 1>()
----> 1 tp.fetch_points_of_sales()
File /usr/local/lib/python3.10/site-packages/django_afip/models.py:468, in TaxPayer.fetch_points_of_sales(self, ticket)
465 results = []
466 for pos_data in response.ResultGet.PtoVenta:
467 results.append(
--> 468 PointOfSales.objects.update_or_create(
469 number=pos_data.Nro,
470 owner=self,
471 defaults={
472 "issuance_type": pos_data.EmisionTipo,
473 "blocked": pos_data.Bloqueado == "N",
474 "drop_date": parsers.parse_date(pos_data.FchBaja),
475 },
476 )
477 )
479 return results
File /usr/local/lib/python3.10/site-packages/django/db/models/manager.py:85, in BaseManager._get_queryset_methods.<locals>.create_method.<locals>.manager_method(self, *args, **kwargs)
84 def manager_method(self, *args, **kwargs):
---> 85 return getattr(self.get_queryset(), name)(*args, **kwargs)
File /usr/local/lib/python3.10/site-packages/django/db/models/query.py:608, in QuerySet.update_or_create(self, defaults, **kwargs)
604 self._for_write = True
605 with transaction.atomic(using=self.db):
606 # Lock the row so that a concurrent update is blocked until
607 # update_or_create() has performed its save.
--> 608 obj, created = self.select_for_update().get_or_create(defaults, **kwargs)
609 if created:
610 return obj, created
File /usr/local/lib/python3.10/site-packages/django/db/models/query.py:588, in QuerySet.get_or_create(self, defaults, **kwargs)
586 with transaction.atomic(using=self.db):
587 params = dict(resolve_callables(params))
--> 588 return self.create(**params), True
589 except IntegrityError:
590 try:
File /usr/local/lib/python3.10/site-packages/django/db/models/query.py:453, in QuerySet.create(self, **kwargs)
451 obj = self.model(**kwargs)
452 self._for_write = True
--> 453 obj.save(force_insert=True, using=self.db)
454 return obj
File /usr/local/lib/python3.10/site-packages/django/db/models/base.py:739, in Model.save(self, force_insert, force_update, using, update_fields)
736 if loaded_fields:
737 update_fields = frozenset(loaded_fields)
--> 739 self.save_base(using=using, force_insert=force_insert,
740 force_update=force_update, update_fields=update_fields)
File /usr/local/lib/python3.10/site-packages/django/db/models/base.py:776, in Model.save_base(self, raw, force_insert, force_update, using, update_fields)
774 if not raw:
775 parent_inserted = self._save_parents(cls, using, update_fields)
--> 776 updated = self._save_table(
777 raw, cls, force_insert or parent_inserted,
778 force_update, using, update_fields,
779 )
780 # Store the database on which the object was saved
781 self._state.db = using
File /usr/local/lib/python3.10/site-packages/django/db/models/base.py:881, in Model._save_table(self, raw, cls, force_insert, force_update, using, update_fields)
878 fields = [f for f in fields if f is not meta.auto_field]
880 returning_fields = meta.db_returning_fields
--> 881 results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
882 if results:
883 for value, field in zip(results[0], returning_fields):
File /usr/local/lib/python3.10/site-packages/django/db/models/base.py:919, in Model._do_insert(self, manager, using, fields, returning_fields, raw)
914 def _do_insert(self, manager, using, fields, returning_fields, raw):
915 """
916 Do an INSERT. If returning_fields is defined then this method should
917 return the newly created data for the model.
918 """
--> 919 return manager._insert(
920 [self], fields=fields, returning_fields=returning_fields,
921 using=using, raw=raw,
922 )
File /usr/local/lib/python3.10/site-packages/django/db/models/manager.py:85, in BaseManager._get_queryset_methods.<locals>.create_method.<locals>.manager_method(self, *args, **kwargs)
84 def manager_method(self, *args, **kwargs):
---> 85 return getattr(self.get_queryset(), name)(*args, **kwargs)
File /usr/local/lib/python3.10/site-packages/django/db/models/query.py:1270, in QuerySet._insert(self, objs, fields, returning_fields, raw, using, ignore_conflicts)
1268 query = sql.InsertQuery(self.model, ignore_conflicts=ignore_conflicts)
1269 query.insert_values(fields, objs, raw=raw)
-> 1270 return query.get_compiler(using=using).execute_sql(returning_fields)
File /usr/local/lib/python3.10/site-packages/django/db/models/sql/compiler.py:1416, in SQLInsertCompiler.execute_sql(self, returning_fields)
1414 with self.connection.cursor() as cursor:
1415 for sql, params in self.as_sql():
-> 1416 cursor.execute(sql, params)
1417 if not self.returning_fields:
1418 return []
File /usr/local/lib/python3.10/site-packages/django/db/backends/utils.py:98, in CursorDebugWrapper.execute(self, sql, params)
96 def execute(self, sql, params=None):
97 with self.debug_sql(sql, params, use_last_executed_query=True):
---> 98 return super().execute(sql, params)
File /usr/local/lib/python3.10/site-packages/django/db/backends/utils.py:66, in CursorWrapper.execute(self, sql, params)
65 def execute(self, sql, params=None):
---> 66 return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
File /usr/local/lib/python3.10/site-packages/django/db/backends/utils.py:75, in CursorWrapper._execute_with_wrappers(self, sql, params, many, executor)
73 for wrapper in reversed(self.db.execute_wrappers):
74 executor = functools.partial(wrapper, executor)
---> 75 return executor(sql, params, many, context)
File /usr/local/lib/python3.10/site-packages/django/db/backends/utils.py:79, in CursorWrapper._execute(self, sql, params, *ignored_wrapper_args)
77 def _execute(self, sql, params, *ignored_wrapper_args):
78 self.db.validate_no_broken_transaction()
---> 79 with self.db.wrap_database_errors:
80 if params is None:
81 # params default might be backend specific.
82 return self.cursor.execute(sql)
File /usr/local/lib/python3.10/site-packages/django/db/utils.py:90, in DatabaseErrorWrapper.__exit__(self, exc_type, exc_value, traceback)
88 if dj_exc_type not in (DataError, IntegrityError):
89 self.wrapper.errors_occurred = True
---> 90 raise dj_exc_value.with_traceback(traceback) from exc_value
File /usr/local/lib/python3.10/site-packages/django/db/backends/utils.py:84, in CursorWrapper._execute(self, sql, params, *ignored_wrapper_args)
82 return self.cursor.execute(sql)
83 else:
---> 84 return self.cursor.execute(sql, params)
DataError: value too long for type character varying(24)
For context:
django-afip/django_afip/models.py
Lines 460 to 462 in ef2e3c8
The response in the line above is:
{
'ResultGet': {
'PtoVenta': [
{
'Nro': 7,
'EmisionTipo': 'CAEA - Ri Iva CONTINGENCIA',
'Bloqueado': 'N',
'FchBaja': 'NULL'
}
]
},
'Errors': None,
'Events': None
}
This results in a length of 26 characters for EmisionTipo
, which is too long for the issuance_type
field defined in PointOfSales
model.
Huh, I've never seen this value before. Do you know if there is a list of all possible values? If so we can check the longest possible value. Otherwise, we can just extend it to 32.
I really don't know, in the developers manual it's says that the EmisionTipo
has a kind String(8)
but I'll ask those AFIP guys and I post the response.
Thanks. If we don't get a reply in a couple of days, we can push this to just 32
.
The response from AFIP sri team:
Segun lo tratado con las areas intervinientes se remite lo informado a efectos de brindar una solucion al presente requerimiento.
En base al analisis tecnico realizado se verifica que la longitud maxima es de 200 BYTE
Saludos
-----------------------------------
Atte.
Div. Centro de Servicios de Tecnologia
[sri@afip.gob.ar](mailto:sri@afip.gob.ar)
So we can push to 32
as you suggested, until another weird value is returned.