Украинское сообщество программистов

Пробуем Pylons, часть 1: install, db setup

cleg
Опубликовано 27.04.2007 в Статьи

Всякий человек естественно пытается облегчить себе жизнь. Программисты – ярко выраженное доказательство этого принципа. Так уж сложилось, что по ходу работы мне необходимо создавать множество мелких Web-приложений, для решения небольших текущих задач. Ну а поскольку использование PHP мне не доставляет удовольствия чисто эмоционально, я решил попробовать для этих целей Python.

Для начала был опробован очень неплохой пакет httpy, но его функциональность в области “усиленного облегчения жизни” явно очень аскетична. Услышав краем уха волшебное слово фреймворк (как это лучше всего перевести на русский?) я ринулся на «раскопки» этой информации.
В ходе опробования самых распространенных Python фреймворков я для себя остановился на Pylons.

Хочу сразу пояснить, что TurboGears я пока не рассматривал подробно, так как у них до сих пор нет версии для Python 2.5, а в Django до сих пор по моему дилетантскому мнению обладает слишком большим количеством «магии».

К плюсам Pylons можно отнести во-первых заимствование лучший идей мегамодного Rails, во-вторых очень высокая гибкость, выражающаяся в поддержке множества шаблонных движков, ORM и т.д. я надеюсь что в ходе изучения смогу попробовать многие их них изучив массу полезных инструментов.

Для начала, рассмотрим установку данного фреймворка. Проще всего это сделать используя скрипт easy_install (если он уже установлен в системе).

<pre>$easy_install Pylons</pre>

Для тех, чей доступ в интернет перекрыт злобными прокси-серверами, я бы порекомендовал установить переменную окружения HTTP_PROXY, равную URL прокси-сервера. По крайней мере, именно это решение позволило мне насладиться автоматической установкой Pylons.
Если скрипта easy_install у вас нет, то вам необохдимо скачать http://peak.telecommunity.com/dist/ez_setup.py и выполнить его следующим образом.

<pre>$ python ez_setup.py Pylons</pre>

Кроме установки базовых компонент Pylons, можно инсталлировать еще ряд дополнительных. Делается это командой:

<pre>$easy_install Pylons[компонент]</pre>

Где компонент может быть одним из следующих.
- pudge – поддержка сборки документации (подробности тут). Разработчики отмечают что часть инструментов данного проекта все еще находится в разработке и нестабильна.
- genshi, cheetah, kid – поддержка соответсвующих шаблонных движков (подробности тут)
- full – все вышеперечисленное

Обновить Pylons так же очень просто. Независимо от варианта установки, обновление делается одной командой:

<pre>$ easy_install -U Pylons</pre>

Хотя следует отметить, что у меня после обновления таким образом до 0.9.5 Pylons оказался поломан, но разбираться в чем была причина – честно говоря было лень, и переустановка решила все проблемы.

Кстати, для пользователей ОС для домохозяек рекомендуется включить в PATH каталог Scripts, расположенный в каталоге python. Это поможет проще использовать утилиту paster.

Теперь давайте опробуем работу свежеустановленного ферймворка на каком-нибудь конкретном примере.

В роли примера, пожалуй, выступит онлайновый телефонный справочник.

Для начала создадим пустой проект. Для этого необходимо перейти в каталог проектов и там выполнить команду:

<pre>$ paster create --template=pylons phones</pre>

После этого будет создана структура каталогов будущего проекта. Описывать ее подробно я не буду, так как это неплохо сделано в руководстве.

Для теста я использую обычно базу SQLite (хозяевам Python 2.5 уже повезло иметь ее в дистрибутиве, остальным придется доставить соответствующий пакет).

Настроим базу данных используемую нашим приложением. Для этого необходимо отредактировать файл development.ini в корне проекта, поменяв там значение параметра:

<pre>sqlalchemy.dburi = sqlite:///%(here)s/phones.db</pre>

Теперь приступим к созданию моделей. Модели можно редактировать прямо в файле __init__.py в каталоге phones/models

Предварительная версия модели выглядит так:

<pre>from sqlalchemy import *
from sqlalchemy.ext.assignmapper import assign_mapper
from pylons.database import create_engine
from pylons.database import session_context as ctx

meta = MetaData()

persons_table = Table('persons', meta,
Column('id', Integer, primary_key=True),
Column('name', String(40)),
Column('department', Integer, ForeignKey('departments.id')),
Column('email', String(40)),
Column('phone', String(16)),
Column('phone_int', String(6))
)

contacts_table = Table('contacts', meta,
Column('id', Integer, primary_key=True),
Column('type', Integer),
Column('contact', String(40)),
Column('person_id', Integer, ForeignKey('persons.id'))
)

departments_table = Table('departments', meta,
Column('id', Integer, primary_key=True),
Column('name', String(40))
)

class Person(object):
def __str__(self):
return "%s [%s]" % (self.name, self.department)

class Contact(object):
def __str__(self):
return self.contact

contact_mapper = assign_mapper(ctx, Contact, contacts_table)
person_mapper = assign_mapper(ctx, Person, persons_table, properties={'contacts':relation(Contact)})</pre>

Мы создаем три таблицы:
- persons – основная таблица с контактной информацией
- contacts – дополнительные контактные данные (если понадобится что-то нестандартное)
- departmens – таблица подразделений

Кроме того, создаем обеъкты для ORM, которые связываем с соответствующими таблицами функцией assign_mapper.

Теперь нам необходимо обеспечить развертывание данной базы при инсталляции приложения. Для этого в файл websetyp.py, находящийся в корне проекта необходимо добавить следующие строки:

<pre>import paste.deploy
from pylons.database import create_engine
import phones.models as model

def setup_config(command, filename, section, vars):
conf = paste.deploy.appconfig('config:' + filename)
conf.update(dict(app_conf=conf.local_conf, global_conf=conf.global_conf))
paste.deploy.CONFIG.push_process_config(conf)

uri = conf['sqlalchemy.dburi']
engine = create_engine(uri)
print "Connecting to database %s" % uri
model.meta.connect(engine)
print "Creating tables"
model.meta.create_all()</pre>

Теперь, если все сделано правильно, команда

<pre>$ paster setup-app development.ini</pre>

приведет к созданию нашей базы.

Продолжение статьи можно найти тут.

Теги: ,

1 звезда2 звезды3 звезды4 звезды5 звезд (3 голосов, средний: 4 из 5)
Загрузка ... Загрузка ...
Распределение голосов

Понравилась статья? Подпишись на обновления по RSS/E-mail

Подписаться, не оставляя комментарий

Все комментарии (23) к “Пробуем Pylons, часть 1: install, db setup” RSS

  1. pythy

    Исходник поправь, код съехал.

    Статья понравилась. Жде продолжения.

  2. CB

    Використовуйте тег <pre> для блоків коду

  3. cleg

    pythy говорит: 27.04.2007 в 19:34

    Исходник поправь, код съехал.

    Статья понравилась. Жде продолжения.

    спасибо :-)

    CB говорит: 27.04.2007 в 20:06

    Використовуйте тег для блоків коду

    я использовал тег но как его недостаточно. сейчас исправлю.

  4. slav0nic

    молодец

  5. alafin

    Отличная работа!

  6. Maximbo

    Про “чёрную магию” Django — ничего подобного. Не будем плодить мифы?

  7. cleg

    Про “чёрную магию” Django — ничего подобного. Не будем плодить мифы?

    я не говорю про черную… просто в джанго многие вещи спрятаны больше “вглубь”, по сравнению с другими фреймворками. это для новичка типа меня и кажется более “магическим”
    я всего лишь высказываю свое мнение.

  8. Сергей

    Откуда у Contact возьмется атрибут phone? В схеме phone принадлежит Person.

  9. cleg

    Откуда у Contact возьмется атрибут phone? В схеме phone принадлежит Person.

    мдя. это пролезло из старой версии.
    исправил.

  10. Ard

    Что-то сначала easy_install поругался:
    error: Could not find suitable distribution for Requirement.parse(’nose>=0.9.2,

  11. cleg

    Пилоны при инсталляции не смогли поставить Nose нужной версии. Видать что-то натуплено с описанием зависимости :-)
    Но без nose ЕМНИП все должно фпалне работать.

  12. Ingvar

    Вроди все по примеру сделал, но при “paster setup-app” вылазит:
    “import phones.models as model
    ImportError: No module named models”
    В каком “py” они должны лежать, я так понимаю что этот модуль автоматом созадется paster-ом?

  13. cleg

    Можно полный трейс?

  14. Ingvar

    создаем проект

    c:\web\Python25>paster create –template=pylons phones
    Selected and implied templates:
    pylons#pylons Pylons application template

    Variables:
    egg: phones
    package: phones
    project: phones
    Creating template pylons
    Creating directory .\phones
    Recursing into +egg+.egg-info
    Creating .\phones\phones.egg-info/
    Copying paste_deploy_config.ini_tmpl_tmpl to .\phones\phones.egg-info\paste_
    deploy_config.ini_tmpl
    Recursing into +package+
    Creating .\phones\phones/
    Copying __init__.py_tmpl to .\phones\phones\__init__.py
    Recursing into config
    Creating .\phones\phones\config/
    Copying __init__.py_tmpl to .\phones\phones\config\__init__.py
    Copying environment.py_tmpl to .\phones\phones\config\environment.py
    Copying middleware.py_tmpl to .\phones\phones\config\middleware.py
    Copying routing.py_tmpl to .\phones\phones\config\routing.py
    Recursing into controllers
    Creating .\phones\phones\controllers/
    Copying __init__.py_tmpl to .\phones\phones\controllers\__init__.py
    Copying error.py_tmpl to .\phones\phones\controllers\error.py
    Copying template.py_tmpl to .\phones\phones\controllers\template.py
    Recursing into lib
    Creating .\phones\phones\lib/
    Copying __init__.py_tmpl to .\phones\phones\lib\__init__.py
    Copying app_globals.py_tmpl to .\phones\phones\lib\app_globals.py
    Copying base.py_tmpl to .\phones\phones\lib\base.py
    Copying helpers.py_tmpl to .\phones\phones\lib\helpers.py
    Recursing into model
    Creating .\phones\phones\model/
    Copying __init__.py_tmpl to .\phones\phones\model\__init__.py
    Recursing into public
    Creating .\phones\phones\public/
    Copying index.html_tmpl to .\phones\phones\public\index.html
    Recursing into templates
    Creating .\phones\phones\templates/
    Recursing into tests
    Creating .\phones\phones\tests/
    Copying __init__.py_tmpl to .\phones\phones\tests\__init__.py
    Recursing into functional
    Creating .\phones\phones\tests\functional/
    Copying __init__.py_tmpl to .\phones\phones\tests\functional\__init__.py

    Copying test_models.py_tmpl to .\phones\phones\tests\test_models.py
    Copying websetup.py_tmpl to .\phones\phones\websetup.py
    Copying MANIFEST.in_tmpl to .\phones\MANIFEST.in
    Copying README.txt_tmpl to .\phones\README.txt
    Copying development.ini_tmpl to .\phones\development.ini
    Recursing into docs
    Creating .\phones\docs/
    Copying index.txt_tmpl to .\phones\docs\index.txt
    Recursing into ez_setup
    Creating .\phones\ez_setup/
    Copying README.txt to .\phones\ez_setup\README.txt
    Copying __init__.py to .\phones\ez_setup\__init__.py
    Copying setup.cfg_tmpl to .\phones\setup.cfg
    Copying setup.py_tmpl to .\phones\setup.py
    Copying test.ini_tmpl to .\phones\test.ini
    Running c:\web\Python25\python.exe setup.py egg_info
    Adding Pylons to paster_plugins.txt
    Adding WebHelpers to paster_plugins.txt

  15. Ingvar

    устанавливаем:

    Microsoft Windows [Version 5.2.3790]
    (C) Copyright 1985-2003 Microsoft Corp.

    c:\web\Python25\phones>paster setup-app development.ini
    c:\web\Python25\phones\phones\websetup.py:7: DeprecationWarning: pylons.database
    is deprecated, and will be removed from a future version of Pylons. SQLAlchemy
    users are recommended to migrate to SAContext (http://cheeseshop.python.org/pypi
    /SAContext) for similar functionality
    from pylons.database import create_engine
    Traceback (most recent call last):
    File “c:\web\Python25\Scripts\paster-script.py”, line 8, in
    load_entry_point(’pastescript==1.3.6dev-r6755′, ‘console_scripts’, ‘paster’)
    ()
    File “c:\web\python25\lib\site-packages\pastescript-1.3.6dev_r6755-py2.5.egg\p
    aste\script\command.py”, line 78, in run
    invoke(command, command_name, options, args[1:])
    File “c:\web\python25\lib\site-packages\pastescript-1.3.6dev_r6755-py2.5.egg\p
    aste\script\command.py”, line 117, in invoke
    exit_code = runner.run(args)
    File “c:\web\python25\lib\site-packages\pastescript-1.3.6dev_r6755-py2.5.egg\p
    aste\script\appinstall.py”, line 68, in run
    return super(AbstractInstallCommand, self).run(new_args)
    File “c:\web\python25\lib\site-packages\pastescript-1.3.6dev_r6755-py2.5.egg\p
    aste\script\command.py”, line 212, in run
    result = self.command()
    File “c:\web\python25\lib\site-packages\pastescript-1.3.6dev_r6755-py2.5.egg\p
    aste\script\appinstall.py”, line 456, in command
    self, config_file, section, self.sysconfig_install_vars(installer))
    File “c:\web\python25\lib\site-packages\pastescript-1.3.6dev_r6755-py2.5.egg\p
    aste\script\appinstall.py”, line 583, in setup_config
    mod = import_string.try_import_module(mod_name)
    File “c:\web\python25\lib\site-packages\paste-1.4-py2.5.egg\paste\util\import_
    string.py”, line 81, in try_import_module
    return import_module(module_name)
    File “c:\web\python25\lib\site-packages\paste-1.4-py2.5.egg\paste\util\import_
    string.py”, line 67, in import_module
    mod = __import__(s)
    File “c:\web\Python25\phones\phones\websetup.py”, line 8, in
    import phones.models as model
    ImportError: No module named models

  16. Ingvar

    все сделал по примеру
    в каком *.py должен лежать модуль “phones.models”?

  17. Ingvar

    еще одна была заморочка при установке: я думал sqlalchemy идет в комплекте с pylons, поэтому доставлял его потом отдельно командой
    “python.exe ez_setup.py SQLAlchemy==0.3.10″

  18. Ingvar

    Интересное замечание от Paster-а: “DeprecationWarning: pylons.database
    is deprecated, and will be removed from a future version of Pylons. SQLAlchemy
    users are recommended to migrate to SAContext” – гибкость модульности в действии :)

  19. cleg

    в каком *.py должен лежать модуль “phones.models”?

    в каталоге phones есть католог models. его можно использовать как пакет. для єтг надо модели описать в нем в файле __init__.py
    тогда можно будет импортировать phones.models

    Интересное замечание от Paster-а: “DeprecationWarning: pylons.database
    is deprecated, and will be removed from a future version of Pylons. SQLAlchemy
    users are recommended to migrate to SAContext” – гибкость модульности в действии

    более тесная интеграция это зачасту положительно.

  20. Ingvar

    Зависит от трафика между модулями, и от того как сам подойдешь к архитектуре :)

    Ошибка была и со вставленным кодом
    в “c:\web\Python25\phones\phones\model\__init__.py”:
    from sqlalchemy import *
    from sqlalchemy.ext.assignmapper import assign_mapper
    from pylons.database import create_engine
    from pylons.database import session_context as ctx

    meta = MetaData()

    persons_table = Table(’persons’, meta,
    Column(’id’, Integer, primary_key=True),
    Column(’name’, String(40)),
    Column(’department’, Integer, ForeignKey(’departments.id’)),
    Column(’email’, String(40)),
    Column(’phone’, String(16)),
    Column(’phone_int’, String(6))
    )

    contacts_table = Table(’contacts’, meta,
    Column(’id’, Integer, primary_key=True),
    Column(’type’, Integer),
    Column(’contact’, String(40)),
    Column(’person_id’, Integer, ForeignKey(’persons.id’))
    )

    departments_table = Table(’departments’, meta,
    Column(’id’, Integer, primary_key=True),
    Column(’name’, String(40))
    )

    class Person(object):
    def __str__(self):
    return “%s [%s]” % (self.name, self.department)

    class Contact(object):
    def __str__(self):
    return self.contact

    contact_mapper = assign_mapper(ctx, Contact, contacts_table)
    person_mapper = assign_mapper(ctx, Person, persons_table, properties={’contacts’:relation(Contact)})

  21. Ingvar

    В общем, ошибка “ImportError: No module named models” возникает на pylons-0.9.6rc2-py2.5. на pylons-0.9.5 без проблем.

  22. cleg

    а… я не следил. видать что-то поменяли :-)

  23. markko

    phones.models нужно исправить на phones.model
    у меня другие грабли:
    Error Traceback
    clear this
    clear this
    Module phones.controllers.phone:14 in index
    > c.persons = Person.select()
    exceptions.TypeError: unbound method select() must be called with Person instance as first argument (got nothing instead)

Оставить комментарий

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

Архив

Добавить статью

Станьте автором нашего сайта!

Какие материалы подходят для публикации? — Такие.

Присылайте статьи на editors@developers.org.ua.

Подробнее.

Популярные теги

Все теги

Комментарии

Последние комментарии

интернет магазин бытовая техника магазин Laptoper