Разделить строку по длине байта в Python - PullRequest
0 голосов
/ 19 ноября 2018

У меня есть ситуация, когда мне нужно вставить более 4000 символов в Oracle VARCHAR, и мне было рекомендовано не использовать CLOB.Предложенное решение состояло в том, чтобы разделить его на 2 столбца, по 4000 и 8000.Я сделал код динамическим, чтобы можно было обрабатывать количество столбцов X для повторного использования.Он работал отлично, проходил тестирование и т. Д., Пока не был развернут, и кто-то скопировал и вставил из продукта Microsoft, и он сломался, потому что в функции было сгенерировано более 4000 байтов.Я не рассматривал юникод.

Я попробовал несколько идей, чтобы решить эту проблему, прежде чем остановиться на одном, где я начинаю с 4000 символов, а если длина байта превышает 4000, удалите символ и снова проверьте длину байта.Это работает, но мне интересно, есть ли лучшее решение.Функция также изменяет имена столбцов с 'column' на 'column1', 'column2', ... и т. Д.

 text = data[key]
 index = 1
 while text:
     length = 4000
     while len(text[0:length].encode('utf-8')) > 4000:
          length -= 1
     data['{}{}'.format(key, index)] = text[0:length]
     text = text[length:]
     index += 1
 del data[key]

Ответы [ 2 ]

0 голосов
/ 28 ноября 2018

Я в итоге объединил G.Андерсонс ссылка с моим кодом.Он более эффективен в том смысле, что он не кодирует для каждой проверки длины.

    encoded_text = data[key].encode('utf-8')
    index = 1
    while encoded_text:
        length = min(4000, len(encoded_text))
        if len(encoded_text) > 4000:
            while (encoded_text[length] & 0xc0) == 0x80:
                length -= 1
        data['{}{}'.format(key, index)] = encoded_text[:length].decode('utf-8')
        encoded_text = encoded_text[length:]
        index += 1
    del data[key]

Я также играл с идеей использования encode('unicode-escape'), чтобы обойти проблему с юникодом, но это может потенциально более чем удвоить моюдлина строки

0 голосов
/ 20 ноября 2018

Проверьте, действовал ли ваш совет по отношению к объектам CLOB, или он был основан на старой информации о доступе к объектам LOB с использованием локаторов.

Лучшая практика для "маленьких" объектов CLOB в cx_Oracle - представлять их как строки: ваш код будет простым и все же эффективным. Смотрите пример https://github.com/oracle/python-cx_Oracle/blob/master/samples/ReturnLobsAsStrings.py

Другое решение - использовать последнюю версию Oracle DB, которая поддерживает 32K VARCHAR2.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...