Как сделать так, чтобы в Python поддерживалась неподдерживаемая escape-последовательность Юникода?

#python #django #postgresql

Вопрос:

Я пытаюсь создать объект Listing в своем приложении django, но получаю следующее исключение :

UntranslatableCharacter: unsupported Unicode escape sequence .

Как я могу решить эту проблему ?

models.py

 class Listing(models.Model):
    data = JSONField(null=True, blank=True)
    dt = models.DateTimeField(null=True)
    dt_created = models.DateTimeField(auto_now=True)
    objects = DataFrameManager()  # activate custom manager
 

Пример кода

 from requests import Request, Session
from requests.exceptions import ConnectionError, Timeout, TooManyRedirects
import json

log.info('Retrieve listing from CMC')

url = 'https://pro-api.coinmarketcap.com/v1/cryptocurrency/listings/latest'
parameters = {
    'start': '1',
    'limit': '5000',
    'convert': 'USD'
}
headers = {
    'Accepts': 'application/json',
    'X-CMC_PRO_API_KEY': '123xxx',
}

session = Session()
session.headers.update(headers)

try:
    res = session.get(url, params=parameters)
    data = json.loads(res.text)
    
    if data['status']['error_code'] == 0:
        
        dt = timezone.now().replace(minute=0, second=0, microsecond=0)
        Listing.objects.create(dt=dt, data=data)    <--- object creation here 
        log.info('Retrieve listing from CMC complete')

    else:
        log.error('Error while retrieving data from CoinMarketCap')
        log.error("Error: {0}".format(data['status']['error_message']))

except (ConnectionError, Timeout, TooManyRedirects) as e:
    log.error('Error while retrieving data from CoinMarketCap')
    log.error("Error: {0}".format(e))
 

Я проверил data , и это типично dict . Все начинается вот так :

 {'status': {'timestamp': '2021-09-29T14:55:56.378Z',
  'error_code': 0,
  'error_message': None,
  'elapsed': 454,
  'credit_count': 25,
  [...]
 

Это обратная связь :

     ---------------------------------------------------------------------------
UntranslatableCharacter                   Traceback (most recent call last)
~/env/lib/python3.6/site-packages/django/db/backends/utils.py in _execute(self, sql, params, *ignored_wrapper_args)
     85             else:
---> 86                 return self.cursor.execute(sql, params)
     87 

UntranslatableCharacter: unsupported Unicode escape sequence
LINE 1: ...ata_listing" ("data", "dt", "dt_created") VALUES ('{"status"...
                                                             ^
DETAIL:  Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8.
CONTEXT:  JSON data, line 1: ...21-09-29T14:54:10.000Z"}}}, {"id": 11308, "name":...


The above exception was the direct cause of the following exception:

DataError                                 Traceback (most recent call last)
<ipython-input-27-bd20e3459044> in <module>
----> 1 Listing.objects.create(dt=dt, data=data)

~/env/lib/python3.6/site-packages/django/db/models/manager.py in manager_method(self, *args, **kwargs)
     80         def create_method(name, method):
     81             def manager_method(self, *args, **kwargs):
---> 82                 return getattr(self.get_queryset(), name)(*args, **kwargs)
     83             manager_method.__name__ = method.__name__
     84             manager_method.__doc__ = method.__doc__

~/env/lib/python3.6/site-packages/django/db/models/query.py in create(self, **kwargs)
    431         obj = self.model(**kwargs)
    432         self._for_write = True
--> 433         obj.save(force_insert=True, using=self.db)
    434         return obj
    435 

~/env/lib/python3.6/site-packages/django/db/models/base.py in save(self, force_insert, force_update, using, update_fields)
    744 
    745         self.save_base(using=using, force_insert=force_insert,
--> 746                        force_update=force_update, update_fields=update_fields)
    747     save.alters_data = True
    748 

~/env/lib/python3.6/site-packages/django/db/models/base.py in save_base(self, raw, force_insert, force_update, using, update_fields)
    782             updated = self._save_table(
    783                 raw, cls, force_insert or parent_inserted,
--> 784                 force_update, using, update_fields,
    785             )
    786         # Store the database on which the object was saved

~/env/lib/python3.6/site-packages/django/db/models/base.py in _save_table(self, raw, cls, force_insert, force_update, using, update_fields)
    885 
    886             returning_fields = meta.db_returning_fields
--> 887             results = self._do_insert(cls._base_manager, using, fields, returning_fields, raw)
    888             for result, field in zip(results, returning_fields):
    889                 setattr(self, field.attname, result)

~/env/lib/python3.6/site-packages/django/db/models/base.py in _do_insert(self, manager, using, fields, returning_fields, raw)
    924         return manager._insert(
    925             [self], fields=fields, returning_fields=returning_fields,
--> 926             using=using, raw=raw,
    927         )
    928 

~/env/lib/python3.6/site-packages/django/db/models/manager.py in manager_method(self, *args, **kwargs)
     80         def create_method(name, method):
     81             def manager_method(self, *args, **kwargs):
---> 82                 return getattr(self.get_queryset(), name)(*args, **kwargs)
     83             manager_method.__name__ = method.__name__
     84             manager_method.__doc__ = method.__doc__

~/env/lib/python3.6/site-packages/django/db/models/query.py in _insert(self, objs, fields, returning_fields, raw, using, ignore_conflicts)
   1202         query = sql.InsertQuery(self.model, ignore_conflicts=ignore_conflicts)
   1203         query.insert_values(fields, objs, raw=raw)
-> 1204         return query.get_compiler(using=using).execute_sql(returning_fields)
   1205     _insert.alters_data = True
   1206     _insert.queryset_only = False

~/env/lib/python3.6/site-packages/django/db/models/sql/compiler.py in execute_sql(self, returning_fields)
   1389         with self.connection.cursor() as cursor:
   1390             for sql, params in self.as_sql():
-> 1391                 cursor.execute(sql, params)
   1392             if not self.returning_fields:
   1393                 return []

~/env/lib/python3.6/site-packages/django/db/backends/utils.py in execute(self, sql, params)
     98     def execute(self, sql, params=None):
     99         with self.debug_sql(sql, params, use_last_executed_query=True):
--> 100             return super().execute(sql, params)
    101 
    102     def executemany(self, sql, param_list):

~/env/lib/python3.6/site-packages/django/db/backends/utils.py in execute(self, sql, params)
     66 
     67     def execute(self, sql, params=None):
---> 68         return self._execute_with_wrappers(sql, params, many=False, executor=self._execute)
     69 
     70     def executemany(self, sql, param_list):

~/env/lib/python3.6/site-packages/django/db/backends/utils.py in _execute_with_wrappers(self, sql, params, many, executor)
     75         for wrapper in reversed(self.db.execute_wrappers):
     76             executor = functools.partial(wrapper, executor)
---> 77         return executor(sql, params, many, context)
     78 
     79     def _execute(self, sql, params, *ignored_wrapper_args):

~/env/lib/python3.6/site-packages/django/db/backends/utils.py in _execute(self, sql, params, *ignored_wrapper_args)
     84                 return self.cursor.execute(sql)
     85             else:
---> 86                 return self.cursor.execute(sql, params)
     87 
     88     def _executemany(self, sql, param_list, *ignored_wrapper_args):

~/env/lib/python3.6/site-packages/django/db/utils.py in __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
     91 
     92     def __call__(self, func):

~/env/lib/python3.6/site-packages/django/db/backends/utils.py in _execute(self, sql, params, *ignored_wrapper_args)
     84                 return self.cursor.execute(sql)
     85             else:
---> 86                 return self.cursor.execute(sql, params)
     87 
     88     def _executemany(self, sql, param_list, *ignored_wrapper_args):

DataError: unsupported Unicode escape sequence
LINE 1: ...ata_listing" ("data", "dt", "dt_created") VALUES ('{"status"...
                                                             ^
DETAIL:  Unicode escape values cannot be used for code point values above 007F when the server encoding is not UTF8.
CONTEXT:  JSON data, line 1: ...21-09-29T14:54:10.000Z"}}}, {"id": 11308, "name":...
 

Комментарии:

1. Покажите нам полное содержание data .

2. Я добавил обратную связь, спасибо

3. «ПОДРОБНО: escape — значения Unicode нельзя использовать для значений кодовых точек выше 007F, если кодировка сервера не UTF8.» — похоже, вам нужно исправить кодировку сервера.

4. @user2357112supportsMonica как вы думаете, мне следует настроить сервер на UTF8 ?

5. Нет, это то, что вам придется сделать. Или вы используете логическую репликацию.