Посты с тегом разработка (27)

И даже с FogBugz не сложилось

Выбор идеального или приближенного к таковому тикет-трекера для личных проектов это просто какая-то мука. Сколько я уже их перепробовал -- и Trac пытался поднимать, и на bitbucket пытался вести таски по проекту. Все не прет. Bitbucket вообще в последнее время не радует своей нестабильностью и баговатостью, в том числе и в трекере.

Требования у меня-то простые. Трекер должен помогать мне держать в актуальном состоянии фичи для реализации и баги для исправления. Все просто и чтобы без лишних рюшечек.

Наверно самым удобным для меня сейчас является баг-трекер на Google Code. Там у меня есть один активный проект (Djapian), в котором довольно много всего приходится делать именно в тренере. Как-то так сложилось, что он даже в некоторой степени превратился в форум -- там задают вопросы, а я на них отвечаю с резолюцией Invalid. Мне это не очень нравится, зато я накопил опыт его использования. И метки мне там нравятся, и возможность добавить в фавориты какие-то таски, и разумные провязки с репозиторием кода. Да, по workflow наверно самый для меня подходящий. Только вот проектов больше там у меня не предвидится. Во-первых они там все публичные, что не всегда удобно, а во-вторых ни svn, ни даже hg уже не вставляют…

В отчаянии решил попробовать FogBugz. Читал ...

Вначале надо всех переучить

Прежде чем "всё переписать", надо рассказать людям - а что это вообще такое! Многие не понимают ни как правильно писать в асинхронном стиле, а вообще всей этой парадигмы.

Уже достаточно давно мой способ знакомства с новой технологией это подписка на список рассылки и внимательное изучение вопросов, ответов и вообще общего духа сообщества. Так случилось что на рассылку node.js я подписался до знаменитого поста Саймона и смог увидеть резко возросший интерес к теме.

Как это обычно бывает набежало сразу куча восторженных людей и пошли многокилометровые споры о том какой MVC фреймворк надо на базе этого сделать и какой шаблонный движок реализовать. Уже плохо. Но когда люди участвующие в подобных спорах вдруг, так, невзначай, приходят и задают с виду безобидные, но выносящие мозг вопросы как этот или этот, то опускаются руки и кажется что в нашем разработческом мире не всё хорошо.

Люди не понимают сути. Совсем. Причем им как бы интересна технология. Встает вопрос почему? Да модно просто. Такое происходит уже не в первой рассылке которую я наблюдаю. Так же было с CouchDB например.

Кстати, что я заметил -- эти люди в основном пишут на... ruby. Ну не важно:-)

Не понимают они, что новые технологии это не только модный buzzword но и ещё ...

NoSQL: Нереляционные хранилища

Пора нарушить молчание и рассказать о том, что на недавней замечательной конференции 404fest я тоже имел честь выступать с докладом. Посвящен он был модной ныне теме - NoSQL. Доклад получился коротким и поэтому больше политическим чем техническим. Я хотел показать, что этот новый тренд не просто так захватывает умы всё большего числа разработчиков.

Это только первое моё выступление на эту тему, но, я надеюсь, что в скором времени последуют другие на новых площадках


View more documents from Alex Koshelev.

Update: а вот и видео подоспело:

Композиция: ForeignAttributeField

Как вы догадались, я продолжаю тему денормализации и моей реализации композитных полей.

С момента прошлого поста я успел значительно улучшить базовый CompositionField и решить несколько концептуальных проблем.

Итак что же новое появилось:

  • Сделал низкоуровневый CF полноценным классом, который теперь удобно сабклассить и добавлять новый функционал
  • Появилось место для интроспекции. Присоединение к хост модели стало более интеллектуальным из-за возможного отложенного присоединения.
  • Чуть-чуть изменился интерфейс - параметр commit теперь может быть задан для конкретного триггера. Это сугубо практическое изменение, которое помогло решить одну проблему с бесконечной рекурсией.
  • По совету Вани Сагалаева добавил генерацию freeze_FOO метода, который включает/выключает обработку сигналов. Полезно когда надо обработать какие-то данные скопом, а потом так же скопом пересчитать денормализованные поля.

Я грозился написать высокоуровневые обертки над CF чтобы облегчить использование и упростить конечный интерфейс. Сегодня я расскажу о первом сабклассе CF: ForeignAttributeField - поле которое отслеживает изменения некого внешнего поля в связанном объекте. Причем, поле может находится на любом уровне вложенности связи, что иногда очень удобно. Как я уже писал в прошлый раз - поля объектов, на которые непосредственно ссылается модель, так денормализовывать смыла мало. Проще использовать select_related. Но если заветный атрибут лежит глубже и для доступа к нему надо приджоинить, допустим, пять таблиц, то тут уже другой расклад и ...

Красивая композиция

Нет, я не про музыку решил написать. А про композицию данный, агрегацию если хотите.

В джанге на данный момент агрегации в ORM нет. Но как известно скоро должна появиться, а значит жизнь в очередной раз станет проще.

Зачем?

Но на много ли? Да, писать запросы с агрегацией станет проще. Но в большинстве случаешь выполнять запрос для сервера легче не станет. Вот ту на помощь приходит техника денормализации.

Денормализация - это добавления избыточности данных для увеличения производительности чтения данный. Обычно чтение данных требуется гораздо чаще чем их запись, а значит на запись в принципе можно потратить чуть больше времени, за-то потом много раз сэкономить на выборке. Агрегацию я привел в качестве, наверно, самого популярного источника данных для денормализации, но ею конечно не ограничивается применение денормализации. Суть в том, что лучше что-то тяжелое посчитать при записи и сохранить, чем каждый раз при чтении пересчитывать заново.

Наверно многие из вас в своих проектах писали код наподобие такого, тем более, если писали "свой блог движок":

class Post(models.Model):
   comment_count = models.PositiveIntegerField(default=0)

class Comment(models.Model):
   post = models.ForeignKey(Post, related_name="comments")

   def save(self):
      super(Comment, self).save()
      self.post.comment_count = self.post.comments.count()

   def delete(self):
      super(Comment, self).delete ...