5231
Comment: Simple example showing repoze.tm2 with storm in pylons
|
5583
|
Deletions are marked like this. | Additions are marked like this. |
Line 5: | Line 5: |
The example project will just have a simple controller with two action. The first action will add a person to a sqldb database and the second action will list all persons in the database. | The example project will just have a simple controller with two actions. The first action will add a person to a sqldb database and the second action will list all persons in the database. |
Line 7: | Line 7: |
Create the project using | You need to have the following packages: * transaction * zope.interface * repoze.tm2 The following dependencies are required when using Storm 0.12 or lower. They are optional when using the following [[https://lists.ubuntu.com/archives/storm/2008-July/000673.html|patch]] or until the [[https://code.launchpad.net/~jamesh/storm/require-less-zope|require-less-zope]] branch is merged. * zope.security * zope.testing Create the project using paster: |
Line 13: | Line 22: |
As explained in [[http://blog.repoze.org/repoze.tm_with_pylons-20071218.html|this blog]] you need to add repoze.tm2 to the pipeline of your Pylons application. | As explained in [[http://blog.repoze.org/repoze.tm_with_pylons-20071218.html|this blog]] you need to add repoze.tm2 to the pipeline of your Pylons application. This will enable every request to be a transaction. |
Line 15: | Line 24: |
You should add the following pipeline and rename the {{{app:main}}} section. | You should add the following pipeline and rename the {{{app:main}}} section to {{{app:repozestorm}}} in {{{development.ini}}}. |
Line 20: | Line 30: |
storm.database.persons.uri = sqlite:///%(here)s/repozestorm/data/sqlite/persons.db | storm.database.persons.uri = sqlite:///%(here)s/repozestorm/data/persons.db |
Line 35: | Line 45: |
__storm_table__ = "Persons" id = Int(primary=True) firstname = Unicode() |
__storm_table__ = "Persons" id = Int(primary=True) firstname = Unicode() |
Line 71: | Line 81: |
And run it: | Create directory to hold the database and run setup-app: |
Line 74: | Line 84: |
$ mkdir -p repozestorm/data/sqlite | $ mkdir -p repozestorm/data |
Line 79: | Line 89: |
Create a controller for the application: | Create a controller for the application {{{repozestorm/controllers/person.py}}}: |
Line 88: | Line 98: |
from borg.lib.base import * from borg.model.person import Person |
from repozestorm.lib.base import * from repozestorm.model.person import Person |
Line 100: | Line 110: |
Line 106: | Line 116: |
store.add(p) | store.add(p) |
Line 116: | Line 126: |
global_zstorm contains all Storm stores by key. In this example the uri associated with that key is stored in {{{development.ini}}}. | global_zstorm contains all Storm stores by key. In this example the uri associated with that key is stored in {{{development.ini}}}. You can also set a default uri on global_zstorm. |
Line 118: | Line 128: |
Because the application run inside a Repoze.tm2 pipeline, there is no need to call {{{store.commit()}}}. Every request to a controller is a transaction. If an exception is raised the transaction is rolled back or otherwise committed. | Because the application runs inside a Repoze.tm2 pipeline, there is no need to call {{{store.commit()}}}. Every request is a transaction and global_zstorm will register every store to the current transaction. If an exception is raised the transaction is rolled back or otherwise committed. |
Line 120: | Line 130: |
The controller action list calls a mako template (repozestorm/templates/list_persons.mako): | The list controller action calls a mako template {{{repozestorm/templates/list_persons.mako}}} to display a list of persons: |
Line 134: | Line 144: |
% for person in c.persons: <li> ${person.id} ${person.firstname} ${person.lastname} </li> % endfor |
% for person in c.persons: <li>${person.id} ${person.firstname} ${person.lastname}</li> % endfor |
Line 154: | Line 162: |
And show an initially empty list of persons by going to [[http://localhost:5000/person/list]]. Add a person on [[http://localhost:5000/person/new]] and check again on [[http://localhost:5000/person/list]]. | Start off by showing an (initially) empty list of persons by going to [[http://localhost:5000/person/list]]. Add a person by visiting [[http://localhost:5000/person/new]] and check the result on [[http://localhost:5000/person/list]] again. |
Using Storm with Pylons and Repoze.tm2
This example shows how to integrate Storm with Repoze.tm2 in a Pylons application. Repoze.tm2 is a transaction manager which uses Zope's transaction package.
The example project will just have a simple controller with two actions. The first action will add a person to a sqldb database and the second action will list all persons in the database.
You need to have the following packages:
- transaction
- zope.interface
- repoze.tm2
The following dependencies are required when using Storm 0.12 or lower. They are optional when using the following patch or until the require-less-zope branch is merged.
- zope.security
- zope.testing
Create the project using paster:
$ paster create -t pylons RepozeStorm
As explained in this blog you need to add repoze.tm2 to the pipeline of your Pylons application. This will enable every request to be a transaction.
You should add the following pipeline and rename the app:main section to app:repozestorm in development.ini.
[app:repozestorm] use = egg:RepozeStorm full_stack = false storm.database.persons.uri = sqlite:///%(here)s/repozestorm/data/persons.db [pipeline:main] pipeline = egg:Paste#cgitb egg:Paste#httpexceptions egg:repoze.tm2#tm repozestorm
Next define the model for persons repozestorm/model/person.py.
Person will be stored in a sql table called persons. Create that table by using setup-app. But for that to work make repozestorm/websetup.py:
1 """Setup the RepozeStorm application"""
2 import logging
3
4 from paste.deploy import appconfig
5 from pylons import config
6
7 from storm.zope.zstorm import global_zstorm
8
9 from repozestorm.config.environment import load_environment
10
11 log = logging.getLogger(__name__)
12
13 def setup_config(command, filename, section, vars):
14 """Place any commands to setup repozestorm here"""
15 conf = appconfig('config:' + filename, name=section.split(':')[1])
16 load_environment(conf.global_conf, conf.local_conf)
17
18 store = global_zstorm.get('persondb', config['storm.database.persons.uri'])
19 try:
20 store.execute("create table persons "
21 "(id integer primary key, "
22 "firstname varchar, lastname varchar)")
23 store.commit()
24 finally:
25 store.close()
Create directory to hold the database and run setup-app:
$ mkdir -p repozestorm/data $ paster setup-app development.ini#repozestorm Running setup_config() from repozestorm.websetup
Create a controller for the application repozestorm/controllers/person.py:
1 import logging
2
3 from pylons import config
4
5 from storm.zope.zstorm import global_zstorm
6
7 from repozestorm.lib.base import *
8 from repozestorm.model.person import Person
9
10 log = logging.getLogger(__name__)
11
12 class PersonController(BaseController):
13
14 def index(self):
15 # Return a rendered template
16 # return render('/some/template.mako')
17 # or, Return a response
18 return 'Hello World'
19
20 def new(self):
21 store = global_zstorm.get('persondb', config['storm.database.persons.uri'])
22 p = Person()
23 p.firstname = u"Boo"
24 p.lastname = u"Foo"
25 store.add(p)
26 return "Done"
27 #raise Exception('Haha')
28
29 def list(self):
30 store = global_zstorm.get('persondb', config['storm.database.persons.uri'])
31 c.persons = list(store.find(Person))
32 return render('/list_persons.mako')
global_zstorm contains all Storm stores by key. In this example the uri associated with that key is stored in development.ini. You can also set a default uri on global_zstorm.
Because the application runs inside a Repoze.tm2 pipeline, there is no need to call store.commit(). Every request is a transaction and global_zstorm will register every store to the current transaction. If an exception is raised the transaction is rolled back or otherwise committed.
The list controller action calls a mako template repozestorm/templates/list_persons.mako to display a list of persons:
# -*- coding: utf-8 -*- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html> <head> <title>List Persons</title> </head> <body> <div class="content"> <h1 class="main">List of persons</h1> <ul id="persons"> % for person in c.persons: <li>${person.id} ${person.firstname} ${person.lastname}</li> % endfor </ul> </div> </body> </html>
And finally run the example:
$ paster serve --reload development.ini Starting subprocess with file monitor Starting server in PID 1234. serving on 0.0.0.0:5000 view at http://127.0.0.1:5000
Start off by showing an (initially) empty list of persons by going to http://localhost:5000/person/list. Add a person by visiting http://localhost:5000/person/new and check the result on http://localhost:5000/person/list again.