10.26.2010

Populate fake data in django

Задача - нагенерить N рандомных слов, которые хоть чуть-чуть похожи на настоящие слова (то есть подобие слогов). Халява на пайтоне:

>>> def gen_rand_strings(num):
...     import random
...     allchars = [chr(i) for i in range(97, 97+26)]
...     vowels = ['a', 'e', 'i', 'o', 'u', 'y']
...     consonants = [i for i in allchars if i not in vowels]
...     ret = []
...     for i in range(0, num):
...         s = ''
...         rr = random.randint(2, 6)
...         for j in range(1, rr):
...             s += random.choice(consonants)
...             s += random.choice(vowels)
...         ret.append(s)
...     return ret
>>> gen_rand_strings(20)
['vydohefy', 'hete', 'comegihu', 'sarabo', 'tyde', 'ro', 'mojuletabu', 'ruridaviqy', 'my', 'tafaluhy', 'teleniwu', 'xixy', 'cyky', 'hypakelo', 'kicuba', 'jekiqovazu', 'botaveci', 'byru', 'dolizojaca']

Зачем это понадобилось, да вот захотелось набить БД фейковыми данными :) примерно так (по проекту homebudget):

>>> from homebudget.purchases import models
>>> models.PurchaseTag.objects.count()
0
>>> new_tags = gen_rand_strings(20)
>>> for tag in new_tags:
...     ntag = models.PurchaseTag.objects.get_or_create(value=tag, norm_value=tag, owner=usernew)
...     ntag[0].save()
>>> models.PurchaseTag.objects.count()
20
>>>
>>> from datetime import date, timedelta
>>> last = date.today()
>>> dt = date(year=2010,month=05,day=1)
>>> oneday = timedelta(days=1)
>>> while (dt < last):
...     rr = random.randint(3, 10)
...     for i in range(0, rr):
...          tag = models.PurchaseTag.objects.get(value=random.choice(new_tags))
...          price = random.randint(1, 100)
...          purch = gen_rand_string(2)[0]
...          p = models.Purchase(name=purch,quantity=1.,price_for_one=price,price_total=price, purchase_date=dt, owner=usernew)
...          p.save()
...          p.tags.add(tag)
...          p.save()
...     dt += oneday
База забита фейковыми покупками за полгода, к каждой покупке привязан один из 20 новых тагов. Теперь можно спокойно тестить выборки для построения статистики. Халява как она есть.

10.18.2010

хроники django или homebudget part 7

После долго молчания, возвращаемся к нашим баранам.


Во первых, что обязательно нужно описать, так это передвижение с google-code на launchpad. Предпосылки:

  1. во-первых плюсы DVCS системы:
    1. банальные мелочи, у меня есть четыре машины с которых я колбашу код. Естественно, я один, про фитчи думаю один, изменения архаичные, некоторые нужно сразу в главную ветку, другие - только в бранчи. В свн-бранчи все оформлять тупо лень (т.к. о них нужно помнить). По этому колбашу в trunk-е. И синхронизировать 4 машины ой какая проблема - типа вчера уснул и часть не закомитил, а изменения были эпические. Работа встала на других машинах. В распределенной системе - каждая локальная копия по-сути бранч. Работотать на нескольких машинах в разы проще.
    2. смерджить можно все что угодно, без последствий. В свн-е же для мерджа нужные крепкие нервы и холодные разум.
    3. можно без проблем откатиться до любой версии. Кто как, но я это люблю.
  2. во-вторых плюсы launchpad-а:
    1. bazaar собственно.
    2. Хостинг многих опен-сурс проектов, которые я использую (хотя бы убунта и терминатор)
    3. всякие бонусы типа отображения публичного gpg ключа и активности пользователь.
    4. есть публичная страничка на которой отображены все проекты пользователя. В гугль-коде такую не нашел. Мне это критично.
  3. давно хотел провести глобальные изменения архитектуры
    1. есть мой хостинг (пока не рассекреченный), крутится ngnix, заведен джанго-проект. В нем крутится homebudget (как не трудно догадаться). Иногда мне нужно добавлять новые приложения для личных целей (скорее не целей, а идей и экспериментов). Заводить новый процесс под это ой как не хочется, да и не логично. А в старой структуре свн-а был заведен репозиторий прямо на проект, и лежащие внутри приложения. Новые приложения хранятся (или не хранятся вовсе) в разных местах. Ну вот и логичнее всего мне вести репозитории по приложениям, а не по проекту. Так что от репозиторя для проекта было решено отказаться в пользу локального репозиторя. А приложения - в народ.
    2. Еще один плюс приложений - манипулировать гораздо проще. Развертываешь в отдельной папке такую-то ревизию, ставишь на нее симлинк, а старый затираешь. Круто, да круто.
    3. Хотя нужно сказать структура проект-приложение не совсем гибкая. Это не удобно, тупо не удобно. Нужно больше ветвления. Типа переиспользуемые под-приложения.

Как это делалось, да просто как можно догадаться.

  1. изменил все межпроектные линки на использование глобальных "homebudget.purchases" и "homebudget.tagsfield"
  2. вынес маппинг урлов из проектого urls.py в соответствующие файлы приложений. В проектном urls.py теперь стоит просто include bla-bla-bla.
  3. разместил статик контент и темплейты по директориям проектов (т.е. было "homebudget/content/purchases/css", стало "homebudget/purchases/media/css" и тд)
  4. в новый проект добавляется директория типа "static-content", в нее ставятся симлинки на директории "homebudget/purchases/media". MEDIA_ROOT смотрит на директорию "static-content". В итоге: из проекта до его статик файлов можно достучаться по пути "/site-media/purchases/css/" (работает MEDIA_URL, имя проекта, и путь по симлинке).
  5. темплейтные директории прописываются явно в settings.py в TEMPLATES_DIR (типа "/homebudget/purchases/templates/"). Соответствующий код для взятия темплейтов был подправлен.
  6. ну и проекты были добавлены в PYTHONPATH, типа "export PYTHONATH=${PYTHONPATH}:/path/to/project" где-то внутри "~/.bashrc"

Собственно ссылки:


Посты по теме: