Уведомления

Группа в Telegram: @pythonsu

#1 Март 11, 2009 01:58:16

ZZZ
От: Москва
Зарегистрирован: 2008-04-03
Сообщения: 2161
Репутация: +  26  -
Профиль   Адрес электронной почты  

Иерархическая база данных

andreytata
Но раньше использовался на МАС для всех нужд…
Это судьба… :-))) Прошлым летом я перелез с KDE на MacOS X

sypper-pit
А всегда всё новое это ремикс к старому
А если учесть, что меня звали Старым Рокером, то это как раз то, что нужно! :-)))

Блин, вот это вы меня повесилили. Спасибо!

andreytata
Осталось тока добавить четырхбайтовый код типа инфы “чанк” чтобы сделать формат масштабируемым.
А зачем? У меня инфа о файлах хранится в YAML. Притом размер этой инфы не лимитируется (хотя злоупотреблять не стоит). Тип инфы, с точки зрения змеюки, лишь просто словать. Хешируемые ключи – любые значения. Хочу ещё написать более универсальный сериализатор YAML, а то этот PyYAML уж очень питоний… В общем маштабируй как хочешь!
При желании не трудно довавить систему пере/дозаписи… Типа после инфы ещё четыре байта на интегер – адрес следующей инфы.

Ну что, я довёл всё это к рабочему виду. Кому-нить ещё интересно глянуть на код? А то просто так мне лень его кучку собирать… Там ещё кое что из моего используется… Совсем расслабился…



Офлайн

#2 Март 11, 2009 04:47:18

sypper-pit
От: Ulan-Ude(msk)
Зарегистрирован: 2009-01-30
Сообщения: 1102
Репутация: +  6  -
Профиль   Отправить e-mail  

Иерархическая база данных

Я тоже старая роковая обезьяна :) “”“порти всем жизнь и выдавай чужие стихи за свои”“”(с) :)

Офлайн

#3 Март 11, 2009 05:51:05

andreytata
От:
Зарегистрирован: 2009-03-03
Сообщения: 20
Репутация: +  0  -
Профиль   Отправить e-mail  

Иерархическая база данных

YAML, XML, и прочие человекочитаемые форматы использовать просто не могу - слишком медленно для моей специфики.
Скорости ради юзаю cPickle:

from cPickle import loads, dumps
sampledata = {
1 :"simple buff under int key",
"str_key":"simple buff under string key",
3 :( 'tuple','data','stored','under','int key')
}
print sampledata
s=dumps(sampledata) # STORE to string
print s
restored = loads(s) # RETRIEVE from string
print restored

#Shelve use BDB as default DB and cPickle too, and interface of 'shelve' is 'dict':
import shelve
d = shelve.open("sample.db") # OPEN - shelve used DB format BDB as default
d['key'] = sampledata # STORE data at key (overwrites old data if using an existing key)
data = d['key'] # RETRIEVE a COPY of data at key (raise KeyError if no such key)
print data
del d['key'] # DELETE data stored at key (raises KeyError if no such key)
flag = d.has_key('key') # true if the key exists
list = d.keys() # a list of all existing keys (slow!)
d.close() # DO NOT FORGET CLOSE IT !!
Правда ограничение: в словаре ‘d’ ключи исключительно строки, но это легко обойти через my_str_key = cPickle.dumps(my_non_string_key)
сPickle и BDB - модули жестоко плайн Си-шные, маршаллинг используется сишный (кроссплатформенно).
Для меня это и паковшик сетевых пакетов и мини FS и сохранялка настоек пользователя …

ЗЫ: ЧТО МОЖЕТ БЫТЬ БЫСТРЕЕ ИЛИ УДОБНЕЕ ?? :)



Офлайн

#4 Март 12, 2009 04:01:35

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Иерархическая база данных

andreytata
Я понемногу склоняюсь к мысли, что pickle - очень удобный, но далеко не всегда оптимальный формат.

Во первых - слишком он легко идет. Сериализует почти все, что угодно. В этом есть и минусы.

Вчера после работы чуть задержался в офисе. Приятель получил почетное переходящее знамя билдера (мы их ежедневно делаем), а я за компанию.
Плюс хотел юниттестами новое изобретение покрыть полностью и строго. Без них отдашь хорошую задумку людям, а через месяц-два в ней появится куча слабых мест и откровенных ляпов. Заметил: если программист не понял основную мысль дизайна/архитектуры - он начинает “гладить кошку против шерсти”. А на работе на пальцах можно пересчитать тех, кто задумывается: а почему класс А был сделан так, а не как-нибудь иначе? Вот и лепят свои патчики так, что волосы дыбом. Юниттесты позволяют вовремя дать по рукам. Получивший с большой вероятностью подойдет ко мне с вопросом, а там уж я ему заясню генеральную линию партии.
Это - помимо основной задачи: находить баги в коде. С этим тоже есть своя проблема. Если архитектура “правильная” - тесты пишутся легко и непринужденно, в больших количествах. И выполняют свое главное предназначение. Я только относительно недавно смог ощутить это в полной мере. И, думаю, все еще очень далек от совершенства.
Большая часть нашего немальнького кода, естественно, этому критерию не отвечает. Т.е. тесты баги не находят и не могут найти - т.к. для тестирования функции приходится подменять практически все ее окружение. Но тесты пишут, ибо начальство этого настоятельно требует. Результат тоже небесполезен: если ломается тест в результате твоих изменений - то вынужденно следует review, правится либо тест либо код, а чаще все вместе. Заодно есть шанс познакомиться с результатами чужого творчества и увидеть, что успели сделать другие люди/команды. К слову, американы в основной массе очень не любят смотреть чужой код. Наверное, это общая проблема - до этого мне просто сильно везло с коллегами.

Отвлекся.
Возвращаясь к pickle. Тесты в тот вечер я, как вы уже догадались, не писал.
Внезапно сервисы перестали работать. Практически совсем. Каждая транзакция заканчивалась exception и требуемого ответа не было. У нас клиент-сервер, так что сломалась серверная часть. Локальная катастрофа, вечерний неудачный билд не уйдет к тестерам, они не расскажут о новых ошибках, на один день сломается вся структура. Камрад Нил быстро понял, что последний находящийся в офисе чел из команды сервисописателей дупля откровенно не отбивает, окинул острым взором оставшийся народ и безошибочно направился ко мне.

Проблема была вроде бы тривиальная: что-то не могло пройти через pickle потому что было слабой ссылкой (weakref). Как я быстро обнаружил, пытались протолкнуть весьма нетривиальный объект, внутри которого к тому же было колечко (pickle ведь отлично сериализует объекты с циклическими ссылками).
Какой из многочисленных претендентов имел внутри этот самый weakref - непонятно по генерируемому исключению (к слову, использовался cPickle, а от него stacktrace совсем куцый). Путем дедукции и напряжения мозга сообразил, что пытались запиклить объект из нашего ORM (а-ля SQLAlchemy, но в силу наших внутренних особенностей алхимию использовать невозможно, создано ее подобие).
Я и не предполагал, что кому-то прийдет в голову передавать по сетке объект базы данных. Это же невозможно по ахитектурным соображениям: где сессия, к чему теперь информация об изменениях полей, весь концепт рушится. Примерно как недавно кто-то пытался сериализовать boundmethod.
Быстро переопределил для всех сущностей из ORM __getnewargs__, дабы бросал хорошее и информативное исключение. Естественно, на следующем прогоне сразу же поймал вора.
Потребовался крошечный фикс на 10 строк, и успешный билд ушел.
А на следующий день я крепко насел на Тима, лида этих сервисников (к слову, Тим - весьма неглупый парень и голова у него работает как надо). Настоящая ПРОБЛЕМА была в том, что пересылалось ОЧЕНЬ МНОГО ИЗБЫТОЧНЫХ ДАННЫХ. Которые гораздо быстрее было бы получить на приемнике (они у него на самом деле уже есть). Т.е. вместо того, чтобы проталкивать очень большой объект, очень редко изменяемый (обе стороны уже имеют его в своем кеше, следят за изменениями и сами перечитывают когда нужно, прогнозируемые изменения не чаще раза в день) - можно передать его unique key, и подхватить его на другой стороне.
Отчасти ее видели по резкому снижению производительности серверной части. Но ведь «кажется, стало медленней работать» - еще не показатель»
Тим сильно удивился такому положению дел. Предложил быстрый патчик (и он прошел - еще бы, тривиально, когда знаешь в чем дело). Посопротивлялся идее “а давайте напишем свой pickle с нашими ограничениями”.
Это его не спасет, т.к. только свой сериализатор позволит вовремя заорать: не то в меня пихают, на что я согласный!!!
Для начала сделаем свой restricted pickle(унаследоваться от Pickler и UnPickler и зарезать функциональность) , а потом, если будет нужно - перепишем на плюсах, как водится.

Уже практически сказал все, что хотел.
Теперь - во вторых (мелочь).
Специализированный pickle может быть быстрее. Не знаю насколько. Быть может - на “совсем чуть-чуть”. Можно быстрее обрабатывать твои специфические типы, не кодируя их как “наследник от object, лежащий в модуле my_pope.my_cardinal.my_priest.my_guy”, а просто вставив свой префикс для класса.
Улучшение, наверное, будет иметь только академически интересный прирост в скорости. Но к тому, что в стандартный pickle пролезут совсем неожиданно огромные объекты - будь готов. Просто по недосмотру и незнанию. Сейчас ты контролируешь все - но что будет, если проект разрастется?



Офлайн

#5 Март 12, 2009 04:40:01

j2a
От:
Зарегистрирован: 2006-06-29
Сообщения: 869
Репутация: +  1  -
Профиль   Отправить e-mail  

Иерархическая база данных

Андрей Светлов, я читал и улыбался как идиот :D

P.S. Про юниттесты – ППКС, еще с поправкой, что против шерсти можешь и сам начать гладить, через некоторое время после того как последний раз смотрел этот код.



Отредактировано (Март 12, 2009 04:41:45)

Офлайн

#6 Март 12, 2009 05:01:38

ZZZ
От: Москва
Зарегистрирован: 2008-04-03
Сообщения: 2161
Репутация: +  26  -
Профиль   Адрес электронной почты  

Иерархическая база данных

Вот собственно с тем же самым я и столкнулся. Правда тогда это было по собственной глупости… Он всё замечательно пиклит, но потом не всё распикливает. Ну и из соображений безопасности – сам не пробовал “сломать”, но как-то не доверяю ему на фоне возможности запикрить байт-код…
Поэтому либо свой сериализатор пишу, либо вот как сейчас PyYAML, который меня вполне устроил.



Офлайн

#7 Март 12, 2009 05:45:04

Андрей Светлов
От:
Зарегистрирован: 2007-05-15
Сообщения: 3137
Репутация: +  14  -
Профиль   Адрес электронной почты  

Иерархическая база данных

j2a
Рад, что ты улыбнулся.

Кстати, еще летом нас была совсем страшная система создания билда, java ant с вкраплениями питоновского кода.
Когда она ломалась - атас. Никто не проверял, чем закончились эти самые вызовы подпроцессов. Собиралка продолжала работать дальше. Очень долго.
Через примерно 40 минут можно было увидеть - билд не прошел. Почему - догадаться можно. Иногда. Часто - нет. Все очень сложно и запутанно. Повторить - извольте начать все сначала (40 мин, помните?)
И так раз за разом.

Летом я как раз был в Нью-Йорке пару месяцев. И выпала моя неделя почетного билдера. После третьего проблемного билда за мою неделю (мне везло просто сказочно) - озверел. Переписал все к черту.

Теперь, как водится, все делается Питоном. С очень строгими проверками. Все бросает exception и он, заметьте, не съедается как except Exception - долго бил по рукам за такое. Еще бить и бить - есть их у нас в рабочем коде… Если сломалось - стоп с максимально полной инфой.

Билд - пошаговый (Бикинга вовремя почитал). Если шаг был успешен - запомним его (записали в локальный файл). Следующий шаг поломается - получим полную инфу и, самое главное, возможность продолжить с поломавшегося места минуя предыдущие шаги. При это в начале билд делает tag и patch. И есть возможность на этапе, например, сломавшихся юниттестов автоматически обновиться из trunk, сделать patch commit и новый tag. Сильно экономит время.
Все в целом сейчас - 15 мин. Потом идут regression tests, и тут уж помочь ничем нельзя.

Да, мы используем svn без branch for every new task. Такая схема работы - все в trunk. Был бы рад переключиться на bazaar (сторонникам mercurial и git - я вас тоже люблю и уважаю) - но невозможно сейчас по организационным причинам.

Посидев месяц почетным билдером, отладил систему до состояния швейцарских часов.

Теперь у нас скользящий график переходящего знамени. С маленькой поправкой. Индивидум, заваливший билд сегодня - получает знамя на два следующих дня (если завтра будут проблемы от другого индивидума - знамя незамедлительно переходит к виновнику). Очень эффективная система. Позволяющая получить некоторое удовлетворение от того, что ты до хрен знает какого часа решал проблемы, созданные другими.

Сейчас это как правило нерабочие regression - которые 40 мин (летом было 20) и полный стек мало кто проверяет. Я - крайне редко. Но если попался - получи свои 2 почетных дня.

Забавная система получилась.



Отредактировано (Март 12, 2009 06:07:40)

Офлайн

#8 Март 12, 2009 06:48:09

ZZZ
От: Москва
Зарегистрирован: 2008-04-03
Сообщения: 2161
Репутация: +  26  -
Профиль   Адрес электронной почты  

Иерархическая база данных

Андрей Светлов, вы очень интересно пишите. Ваши посты надо распечатывать и на стену вешать… :-)

Кого ещё интересуют пакеты, гляньте сюда: http://pypi.python.org/pypi/zpk/0.2
Собственно оно. Egg собирать пока не стал – ещё успеется, сначала поюзаю…
Ну и в общем там ещё есть что закончить. :-)



Офлайн

#9 Март 12, 2009 11:14:29

Lexander
От:
Зарегистрирован: 2008-09-19
Сообщения: 1139
Репутация: +  33  -
Профиль   Отправить e-mail  

Иерархическая база данных

Андрей Светлов
Индивидум, заваливший билд сегодня - получает знамя на два следующих дня (если завтра будут проблемы от другого индивидума - знамя незамедлительно переходит к виновнику). Очень эффективная система. Позволяющая получить некоторое удовлетворение от того, что ты до хрен знает какого часа решал проблемы, созданные другими.
Хлопаю в ладоши и улыбка до ушей! :)



Офлайн

#10 Март 12, 2009 11:42:19

andreytata
От:
Зарегистрирован: 2009-03-03
Сообщения: 20
Репутация: +  0  -
Профиль   Отправить e-mail  

Иерархическая база данных

Андрей Светлов
andreytata
Я понемногу склоняюсь к мысли, что pickle - очень удобный, но далеко не всегда оптимальный формат.
Во первых - слишком он легко идет. Сериализует почти все, что угодно. В этом есть и минусы.


Специализированный pickle может быть быстрее. Не знаю насколько. Быть может - на “совсем чуть-чуть”. Можно быстрее обрабатывать твои специфические типы, не кодируя их как “наследник от object, лежащий в модуле my_pope.my_cardinal.my_priest.my_guy”, а просто вставив свой префикс для класса.
Улучшение, наверное, будет иметь только академически интересный прирост в скорости. Но к тому, что в стандартный pickle пролезут совсем неожиданно огромные объекты - будь готов. Просто по недосмотру и незнанию. Сейчас ты контролируешь все - но что будет, если проект разрастется?
Андрей, я Змеюкой заразился конкретно от тебя. Причем вися на шее - вплоть до покажи как по списку итерироваться. :) До того как мы встретились мучил исключительно компиляторы. Но и там та-же проблема - отпустил разработку, перестал контролировать всё - И ВСЁ ЧТО НЕЛЬЗЯ ДЕЛАТЬ - ОБЯЗАТЕЛЬНО СДЕЛАЮТ. Просто в гамдевной специфике, быстродействие - главный приоритет а удобный и безопасный API для разработчиков - второстепенный, и как обычно водится, вообще отсутствует как таковой. Посему вынужден контролировать всю разработку аж до момента появления “ДЕКЛАРАТИВНОГО ЯЗЫКА ПРЕДМЕТНОЙ ОБЛАСТИ” элементами которого орудует “РЕДАКТОР УРОВНЕЙ” или на худой конец “РЕДАКТОР ГРАФА”(как в Maya) . Защищаться от безбашенных коллег, до этого момента, практически невозможно - слишком трудоёмко. Но после этого момента - просто. Как в Maya API - желаеш взвалить на ядро Maya заботу по хранению данных - создаеш Maya-атрибут с флагами “storable”, “writable”, цепляеш к своему Maya-узлу и система послушно заобсервит твои данные в момент сохранения графа - и пробилдит граф и восстановит значения в момент загрузки. Но даже этот строгий API не мешает писать плугины вешающие всю систему Maya. Скорее это уже вопрос разработки “Защищенной Операционной Системы” или все дружными рядами уйдем в Эйфель ( который надо было-бы называть “юнит-тест драйвен” язык программированя ).

КОРОЧЕ:
Думаю тут ключевые слова ОБСЕРВЕР и БИЛДЕР полей данных со стороны ЯДРА, и плугиновый ( стороннего разработчика ) функтор COMPUTE выполняемый строго в другом процессе на предмет KILL. :) Особенно в случае если этот COMPUTE редактирует даже не программер, а безбашенный ГАМЕР дорвавшийся до скриптов на предмет ХАЧУ ПОРВАТЬ СИСТЕМУ.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version