- The ``alchemy`` scaffold has been removed.
- The ``routesalchemy`` scaffold has been renamed ``alchemy``.
22 files deleted
15 files modified
1 files renamed
| | |
| | | - Pyramid no longer depends on the Paste or PasteScript packages. |
| | | |
| | | |
| | | Scaffolds |
| | | --------- |
| | | |
| | | - Rendered scaffolds have now been changed to be more relocatable (fewer |
| | | mentions of the package name within files in the package). |
| | | |
| | | - The ``alchemy`` scaffold has been removed. |
| | | |
| | | - The ``routesalchemy`` scaffold has been renamed ``alchemy``. |
| | | |
| | |
| | | |
| | | - Fix SQLA tutorial to match ZODB tutorial. |
| | | |
| | | - Fix other scaffolds to match ZODB scaffold. |
| | | - Fix routesalchemy scaffold to match ZODB scaffold. |
| | | |
| | | - Remove alchemy scaffold. |
| | | |
| | | Nice-to-Have |
| | | ------------ |
| | |
| | | single: starter scaffold |
| | | single: zodb scaffold |
| | | single: alchemy scaffold |
| | | single: routesalchemy scaffold |
| | | |
| | | .. _additional_paster_scaffolds: |
| | | |
| | |
| | | ``zodb`` |
| | | URL mapping via :term:`traversal` and persistence via :term:`ZODB`. |
| | | |
| | | ``routesalchemy`` |
| | | URL mapping via :term:`URL dispatch` and persistence via |
| | | :term:`SQLAlchemy` |
| | | |
| | | ``alchemy`` |
| | | URL mapping via :term:`traversal` and persistence via |
| | | URL mapping via :term:`URL dispatch` and persistence via |
| | | :term:`SQLAlchemy` |
| | | |
| | | .. note:: |
| | |
| | | |
| | | The above command uses the ``pcreate`` command to create a project with the |
| | | ``starter`` scaffold. To use a different scaffold, such as |
| | | ``routesalchemy``, you'd just change the ``-s`` argument value. For example, |
| | | ``alchemy``, you'd just change the ``-s`` argument value. For example, |
| | | on UNIX: |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ bin/pcreate -s routesalchemy MyProject |
| | | $ bin/pcreate -s alchemy MyProject |
| | | |
| | | Or on Windows: |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ Scripts\pcreate routesalchemy MyProject |
| | | $ Scripts\pcreate alchemy MyProject |
| | | |
| | | Here's sample output from a run of ``pcreate`` on UNIX for a project we name |
| | | ``MyProject``: |
| | |
| | | Basic Layout |
| | | ============ |
| | | |
| | | The starter files generated by the ``routesalchemy`` scaffold are |
| | | The starter files generated by the ``alchemy`` scaffold are |
| | | basic, but they provide a good orientation for the high-level patterns common |
| | | to most :term:`url dispatch` -based :app:`Pyramid` projects. |
| | | |
| | |
| | | |
| | | The first positional ``add_view`` argument ``tutorial.views.my_view`` is the |
| | | dotted name to a *function* we write (generated by the |
| | | ``routesalchemy`` scaffold) that is given a ``request`` object and |
| | | ``alchemy`` scaffold) that is given a ``request`` object and |
| | | which returns a response or a dictionary. This view also names a |
| | | ``renderer``, which is a template which lives in the ``templates`` |
| | | subdirectory of the package. When the ``tutorial.views.my_view`` view |
| | |
| | | In a SQLAlchemy-based application, a *model* object is an object |
| | | composed by querying the SQL database which backs an application. |
| | | SQLAlchemy is an "object relational mapper" (an ORM). The |
| | | ``models.py`` file is where the ``routesalchemy`` scaffold |
| | | ``models.py`` file is where the ``alchemy`` scaffold |
| | | put the classes that implement our models. |
| | | |
| | | Let's take a look. First, we need some imports to support later code. |
| | |
| | | |
| | | Your next step is to create a project. :app:`Pyramid` supplies a |
| | | variety of scaffolds to generate sample projects. We will use the |
| | | ``routesalchemy`` scaffold, which generates an application |
| | | ``alchemy`` scaffold, which generates an application |
| | | that uses :term:`SQLAlchemy` and :term:`URL dispatch`. |
| | | |
| | | The below instructions assume your current working directory is the |
| | |
| | | |
| | | .. code-block:: text |
| | | |
| | | $ bin/pcreate -s routesalchemy tutorial |
| | | $ bin/pcreate -s alchemy tutorial |
| | | |
| | | On Windows: |
| | | |
| | | .. code-block:: text |
| | | |
| | | c:\pyramidtut> Scripts\pcreate -s routesalchemy tutorial |
| | | c:\pyramidtut> Scripts\pcreate -s alchemy tutorial |
| | | |
| | | .. note:: If you are using Windows, the ``routesalchemy`` |
| | | .. note:: If you are using Windows, the ``alchemy`` |
| | | scaffold may not deal gracefully with installation into a |
| | | location that contains spaces in the path. If you experience |
| | | startup problems, try putting both the virtualenv and the project |
| | |
| | | :ref:`debug_toolbar`. It allows you to get information about your |
| | | application while you develop. |
| | | |
| | | Decisions the ``routesalchemy`` Scaffold Has Made For You |
| | | Decisions the ``alchemy`` Scaffold Has Made For You |
| | | ================================================================= |
| | | |
| | | Creating a project using the ``routesalchemy`` scaffold makes |
| | | Creating a project using the ``alchemy`` scaffold makes |
| | | the following assumptions: |
| | | |
| | | - you are willing to use :term:`SQLAlchemy` as a database access tool |
| | |
| | | for the ``initialize_sql`` function. |
| | | |
| | | To do so, we'll retain the ``tutorial.tests.ViewTests`` class provided as a |
| | | result of the ``routesalchemy`` project generator. We'll add two |
| | | test classes: one for the ``Page`` model named ``PageModelTests``, one for the |
| | | ``initialize_sql`` function named ``InitializeSqlTests``. |
| | | result of the ``alchemy`` scaffold. We'll add two test classes: one for the |
| | | ``Page`` model named ``PageModelTests``, one for the ``initialize_sql`` |
| | | function named ``InitializeSqlTests``. |
| | | |
| | | Testing the Views |
| | | ================= |
| | |
| | | |
| | | class ZODBProjectTemplate(PyramidTemplate): |
| | | _template_dir = 'zodb' |
| | | summary = 'Pyramid ZODB starter project' |
| | | |
| | | class RoutesAlchemyProjectTemplate(PyramidTemplate): |
| | | _template_dir = 'routesalchemy' |
| | | summary = 'Pyramid SQLAlchemy project using url dispatch (no traversal)' |
| | | summary = 'Pyramid ZODB project using traversal' |
| | | |
| | | class AlchemyProjectTemplate(PyramidTemplate): |
| | | _template_dir = 'alchemy' |
| | | summary = 'Pyramid SQLAlchemy project using traversal' |
| | | summary = 'Pyramid SQLAlchemy project using url dispatch' |
| | | |
old mode 100755
new mode 100644
| | |
| | | from pyramid.config import Configurator |
| | | from sqlalchemy import engine_from_config |
| | | |
| | | from {{package}}.models import appmaker |
| | | from {{package}}.models import initialize_sql |
| | | |
| | | def main(global_config, **settings): |
| | | """ This function returns a WSGI application. |
| | | """ This function returns a Pyramid WSGI application. |
| | | """ |
| | | engine = engine_from_config(settings, 'sqlalchemy.') |
| | | get_root = appmaker(engine) |
| | | config = Configurator(settings=settings, root_factory=get_root) |
| | | initialize_sql(engine) |
| | | config = Configurator(settings=settings) |
| | | config.add_static_view('static', '{{package}}:static', cache_max_age=3600) |
| | | config.add_view('{{package}}.views.view_root', |
| | | context='{{package}}.models.MyRoot', |
| | | renderer="templates/root.pt") |
| | | config.add_view('{{package}}.views.view_model', |
| | | context='{{package}}.models.MyModel', |
| | | renderer="templates/model.pt") |
| | | config.add_route('home', '/') |
| | | config.add_view('{{package}}.views.my_view', |
| | | route_name='home', |
| | | renderer='templates/mytemplate.pt') |
| | | return config.make_wsgi_app() |
| | | |
old mode 100755
new mode 100644
| | |
| | | import transaction |
| | | |
| | | from sqlalchemy.orm import scoped_session |
| | | from sqlalchemy.orm import sessionmaker |
| | | |
| | | from sqlalchemy.ext.declarative import declarative_base |
| | | |
| | | from sqlalchemy.exc import IntegrityError |
| | | |
| | | from sqlalchemy import Column |
| | | from sqlalchemy import Integer |
| | | from sqlalchemy import Unicode |
| | | from sqlalchemy import Column |
| | | |
| | | from sqlalchemy.exc import IntegrityError |
| | | from sqlalchemy.ext.declarative import declarative_base |
| | | |
| | | from sqlalchemy.orm import scoped_session |
| | | from sqlalchemy.orm import sessionmaker |
| | | |
| | | from zope.sqlalchemy import ZopeTransactionExtension |
| | | |
| | |
| | | self.name = name |
| | | self.value = value |
| | | |
| | | class MyRoot(object): |
| | | __name__ = None |
| | | __parent__ = None |
| | | |
| | | def __getitem__(self, key): |
| | | session= DBSession() |
| | | try: |
| | | id = int(key) |
| | | except (ValueError, TypeError): |
| | | raise KeyError(key) |
| | | |
| | | item = session.query(MyModel).get(id) |
| | | if item is None: |
| | | raise KeyError(key) |
| | | |
| | | item.__parent__ = self |
| | | item.__name__ = key |
| | | return item |
| | | |
| | | def get(self, key, default=None): |
| | | try: |
| | | item = self.__getitem__(key) |
| | | except KeyError: |
| | | item = default |
| | | return item |
| | | |
| | | def __iter__(self): |
| | | session= DBSession() |
| | | query = session.query(MyModel) |
| | | return iter(query) |
| | | |
| | | root = MyRoot() |
| | | |
| | | def root_factory(request): |
| | | return root |
| | | |
| | | def populate(): |
| | | session = DBSession() |
| | | model = MyModel(name='test name', value=55) |
| | | model = MyModel(name='root', value=55) |
| | | session.add(model) |
| | | session.flush() |
| | | transaction.commit() |
| | |
| | | populate() |
| | | except IntegrityError: |
| | | transaction.abort() |
| | | return DBSession |
| | | |
| | | def appmaker(engine): |
| | | initialize_sql(engine) |
| | | return root_factory |
| | |
| | | import unittest |
| | | |
| | | from pyramid.config import Configurator |
| | | from pyramid import testing |
| | | |
| | | def _initTestingDB(): |
| | |
| | | session = initialize_sql(create_engine('sqlite://')) |
| | | return session |
| | | |
| | | class TestMyRoot(unittest.TestCase): |
| | | class TestMyView(unittest.TestCase): |
| | | def setUp(self): |
| | | self.config = testing.setUp() |
| | | self.session = _initTestingDB() |
| | | _initTestingDB() |
| | | |
| | | def tearDown(self): |
| | | testing.tearDown() |
| | | self.session.remove() |
| | | |
| | | def _makeOne(self): |
| | | from {{package}}.models import MyRoot |
| | | return MyRoot() |
| | | |
| | | def test___getitem__hit(self): |
| | | from {{package}}.models import MyModel |
| | | root = self._makeOne() |
| | | first = root['1'] |
| | | self.assertEqual(first.__class__, MyModel) |
| | | self.assertEqual(first.__parent__, root) |
| | | self.assertEqual(first.__name__, '1') |
| | | |
| | | def test___getitem__miss(self): |
| | | root = self._makeOne() |
| | | self.assertRaises(KeyError, root.__getitem__, '100') |
| | | |
| | | def test___getitem__notint(self): |
| | | root = self._makeOne() |
| | | self.assertRaises(KeyError, root.__getitem__, 'notint') |
| | | |
| | | def test_get_hit(self): |
| | | from {{package}}.models import MyModel |
| | | root = self._makeOne() |
| | | first = root.get('1') |
| | | self.assertEqual(first.__class__, MyModel) |
| | | self.assertEqual(first.__parent__, root) |
| | | self.assertEqual(first.__name__, '1') |
| | | |
| | | def test_get_miss(self): |
| | | root = self._makeOne() |
| | | self.assertEqual(root.get('100', 'default'), 'default') |
| | | self.assertEqual(root.get('100'), None) |
| | | |
| | | def test___iter__(self): |
| | | root = self._makeOne() |
| | | iterable = iter(root) |
| | | result = list(iterable) |
| | | self.assertEqual(len(result), 1) |
| | | model = result[0] |
| | | self.assertEqual(model.id, 1) |
| | | def test_it(self): |
| | | from {{package}}.views import my_view |
| | | request = testing.DummyRequest() |
| | | info = my_view(request) |
| | | self.assertEqual(info['root'].name, 'root') |
| | | self.assertEqual(info['project'], '{{project}}') |
| | |
| | | def view_root(context, request): |
| | | return {'items':list(context), 'project':'{{project}}'} |
| | | from {{package}}.models import DBSession |
| | | from {{package}}.models import MyModel |
| | | |
| | | def view_model(context, request): |
| | | return {'item':context, 'project':'{{project}}'} |
| | | def my_view(request): |
| | | dbsession = DBSession() |
| | | root = dbsession.query(MyModel).filter(MyModel.name=='root').first() |
| | | return {'root':root, 'project':'{{project}}'} |
| | |
| | | 0.1 |
| | | 0.0 |
| | | --- |
| | | |
| | | - Initial version |
| | | - Initial version |
| | |
| | | |
| | | requires = [ |
| | | 'pyramid', |
| | | 'SQLAlchemy', |
| | | 'transaction', |
| | | 'pyramid_tm', |
| | | 'pyramid_debugtoolbar', |
| | | 'sqlalchemy', |
| | | 'zope.sqlalchemy', |
| | | ] |
| | | |
| | |
| | | author='', |
| | | author_email='', |
| | | url='', |
| | | keywords='web pylons pyramid', |
| | | keywords='web wsgi bfg pylons pyramid', |
| | | packages=find_packages(), |
| | | include_package_data=True, |
| | | zip_safe=False, |
| | | test_suite='{{package}}', |
| | | install_requires = requires, |
| | | tests_require = requires, |
| | | test_suite="{{package}}", |
| | | entry_points = """\ |
| | | [paste.app_factory] |
| | | main = {{package}}:main |
| | |
| | | os.chdir(self.old_cwd) |
| | | |
| | | if __name__ == '__main__': # pragma: no cover |
| | | templates = ['starter', 'alchemy', 'routesalchemy',] |
| | | templates = ['starter', 'alchemy',] |
| | | |
| | | if sys.version_info >= (2, 6) and sys.version_info < (3, 0): |
| | | templates.append('zodb') |
| | |
| | | [pyramid.scaffold] |
| | | starter=pyramid.scaffolds:StarterProjectTemplate |
| | | zodb=pyramid.scaffolds:ZODBProjectTemplate |
| | | routesalchemy=pyramid.scaffolds:RoutesAlchemyProjectTemplate |
| | | alchemy=pyramid.scaffolds:AlchemyProjectTemplate |
| | | [console_scripts] |
| | | bfg2pyramid = pyramid.fixers.fix_bfg_imports:main |