💾 Archived View for r2aze.observer › archive › 2014-10-07-django-the-hypnotist.gmi captured on 2022-06-03 at 23:35:35. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
Нет, конечно не [вот этот Джанго] а [вот этот].
Так вот, вчера я поймал себя на совершенно эпическом баге которым грех не поделиться, потому что в силу особенностей местонахождения, он чуть было не стоил мне кучи неприятностей и насмерть утерянных данных.
Итак, сижу я, ковыряю код, а посреди он вдруг спотыкается и вываливает мне exception, подавившись вот этой строчкой:
{'work_login': u'sch771231'}
Как вы думаете, что здесь не так?
Итак, у нас в базе есть `TextField`, в котором хранится json. Так надо, потому что в исходной базе с которой я работаю и от которой отвертеться никак не могу там тоже json, и вообще, до тех пор пока вы не парсите этот json каждый раз когда обращаетесь к полю, это относительно нормальная практика.
Прочитывая питоновский dictionary из джанговского поля `TextField`, я естественно не забыл сказать ему `json.loads(field)`. Но забыл сказать `json.dumps(dictionary)` при записи обратно. Django, как будто так и надо, с чистой совестью положил туда `dictionary.__str__` То бишь загипнотизировал словарь до полного строкового представления.
То что выводит представление словаря-как-строки – очень похоже на json, поэтому визуально разглядывая результат я ничего не заметил. Но json – это запись объекта по правилам синтаксиса javascript, а питоновское `dictionary.__str__` – это запись словаря по правилам синтаксиса Python, и при попытке `json.loads()` на результат оно подавится почти всегда.
Все вскрылось только потому, что я нашел полезный класс [JSONField] который работает с таким полем сразу как со словарем, и попытался заменить TextField на JSONField.
Самое изящное: В результате, починка бага свелась к _не_изменению той строки, в которой он на самом деле был.
Мораль: Строгая типизация спасла бы меня от этой проблемы и многих других.
➡️ Tech: Огульное программирование
▶️ 2014-10-17: Огульное программирование
© 2001-2022 Eugene Medvedev. All rights reserved, not like that ever stopped anyone, or means anything when not backed up by a corporation.