LINUX.ORG.RU

питоноюникодошняги

 


0

1

есть замечательная штука sqlacodegen с её помощью можно реверсить живые базы в рабочие алхимические модели но если в базе используется кирилица в enum полях, то генерирует вот такие шняги

sost = Column(Enum(??????????????????, ?? ??????????????????), nullable=False, server_default=text("'??????????????????'"))

если в урл базы добавить ?charset=utf8 и выкинуть использование repr то выдаёт уже нормальное поле

sost = Column(Enum('удовлетворительное', 'не удовлетворительное'), nullable=False, server_default=text("'удовлетворительное'"))

но опять не может сохранить ни в файл не передать в |канал, а значит нет и результата

print('\n\n' + model.render().rstrip('\n'), file=outfile)
UnicodeEncodeError: 'ascii' codec can't encode characters in position 1785-1791: ordinal not in range(128)

как исправить?

★★★

Ответ на: комментарий от anonymous

тоже самое

    print('\n\n' + model.render().rstrip('\n').encode('utf-8'), file=outfile)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xd0 in position 1783: ordinal not in range(128)

fMad ★★★
() автор топика
Ответ на: комментарий от anonymous
print(u'\n\n' + model.render().rstrip('\n').encode('utf-8'), file=outfile)

так работает

fMad ★★★
() автор топика

Сам к питону не имею никакого отношения, но как так выходит, что в динамическом языке, вроде питона, существуют методы, которые работают с юникодом и которые нет. Что за прошлый век?

nikolnik ★★★
()
Ответ на: комментарий от nikolnik

да тут вообще ужас с этим юникодом, говорят в третьепитоне всё починят но третьепитон никому не нужен

fMad ★★★
() автор топика

Чтобы исправить, надо не мешать операции с юникодными и байтовыми строками, model.render небось unicode выдает.

bj
()
Ответ на: комментарий от nikita-b

Вместо мажорных несовместимых между собой релизов, можно было бы делать плавные, как в Ruby.

nikolnik ★★★
()
Ответ на: комментарий от bj

дак я вообще не трогаю ничего беру чужую приблуду, реверсю sql базу в модельки а потом с этими модельками через migrate работаю и кругом косяки юникодные

один только мой выискался, с 2009 одна буква в имени таблицы кирилицей была и ни сколько не мешала до сих пор, пока не принудилось во Flaske работать с ней

fMad ★★★
() автор топика
Последнее исправление: fMad (всего исправлений: 1)
Ответ на: комментарий от fMad

А что если извратиться и интерпретировать строки не как строки, а как массив байтов? Если тебе нужно записывать в файл, записывай побайтно. За столько лет существования второго питона, меня может и закидают петунисты своими более рациональными костылями, которые изобрели, может быть, за столько лет, но может написать какой-то модуль или что-то подобное для этого?

nikolnik ★★★
()
Ответ на: комментарий от nikolnik

там уже дали очевидный и всегдашний совет апендить .encode('utf-8')

просто видимо латиноговорящие разрабы совсем не заботятся о поддержке уникода

впрочем и сам этот sqlacodegen сыроват, хотя бы потому, что полностью теряет комментарии к полям, которые бы можно было засунуть в описание полей, что сильно бы сократило время реверса баз

fMad ★★★
() автор топика

В начале скрипта пишем:

import sys
reload(sys) # это хук, чтобы обойти хук разработчиков в служебном модуле интерпретатора `site`
sys.setdefaultencoding('utf-8') # теперь у нас дефолтная кодировка интерпретатора utf-8, 
                                # а не ублюдская ascii, не понимающая кириллицу

Далее усваиваем простое правило: если нужно обрабатывать данные, делаем это в юникоде; если записывать в файл, передавать куда-то — используем байтовые строки. Питон сам ничего конвертировать не будет (единственное, при конкатенации юникодной строки и байтовой, результат будет юникодной строкой, поэтому произойдет неявное приведение байтовой строки к юникоду).
И не забываем читать документацию. Никто не виноват, что вы бездумно смешиваете юникод с байтами.

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

reload(sys) # это хук, чтобы обойти хук разработчиков в служебном модуле интерпретатора `site`

А чё там за хук и что он делает? И не ломается ли чего от того что ты этот хук 'обходишь'?

Bad_ptr ★★★★★
()
Ответ на: комментарий от Bad_ptr

У меня компа под рукой нет, чтобы тебе копипасту из site.py показать. Суть в том, что разрабам не нравилось по какой-то причине, что люди подменяют кодировку по умолчанию. Модуль `site` неявно вызывается при запуске интерпретора в основном для установки import-хука, если я правильно помню. Туда добавили строчку, в которой импортируют модуль sys и удаляют из него функцию setdefaultencoding. Поскольку все импортированные модули (библиотеки) хранятся в специальном хэше, когда погромист импортирует в своем коде модуль sys, питон выполняет поиск по хэшу, находит sys и подсовывает ему вот эту «кастрированную» версию, и прогер получает ошибку, мол нет такой функции в модуле.
Функция reload перезагружает модуль заново, таким образом мы получаем нормальный инстанс sys.
Срамота одним словом :-).

Virtuos86 ★★★★★
()
Ответ на: комментарий от Virtuos86

ты знаешь, я до работы со flask даже не думал про юникод, все базы создаются с юникодом, echo $LANG ru_RU.UTF-8, ну и в шаблонах <meta charset=«utf-8»>

а этот модуль интерпретатора `site` где используется?

fMad ★★★
() автор топика
Ответ на: комментарий от fMad

Это ты зря не думал, разбираться всё равно придется, много тонкостей в работе с файловой системой и с I/O вообще, потому что там всякие локали, ОС-специфичные нюансы etc. Я, кстати, тоже не специалист :-), но если предупрежден, это уже помогает. Кстати говоря, автор фласка много писал и пишет про то, как плох юникод в Python 3.
А что касается site. Еще раз повторю, это чисто служебный модуль интерпретатора; если интересно, можно в него заглянуть, но практической пользы он не имеет. Единственное, там можно посмотреть пример реализации функции импорта модулей. Мне пригодилось один раз — я дописывал текстовый редактор на Python для Symbian смартфонов Nokia, но это сложно назвать типичной задачей.

Virtuos86 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.