summaryrefslogtreecommitdiff
path: root/docs/quick_tour/sqla_demo
diff options
context:
space:
mode:
Diffstat (limited to 'docs/quick_tour/sqla_demo')
-rw-r--r--docs/quick_tour/sqla_demo/.coveragerc3
-rw-r--r--docs/quick_tour/sqla_demo/.gitignore21
-rw-r--r--docs/quick_tour/sqla_demo/CHANGES.txt2
-rw-r--r--docs/quick_tour/sqla_demo/MANIFEST.in2
-rw-r--r--docs/quick_tour/sqla_demo/README.txt41
-rw-r--r--docs/quick_tour/sqla_demo/development.ini23
-rw-r--r--docs/quick_tour/sqla_demo/production.ini26
-rw-r--r--docs/quick_tour/sqla_demo/pytest.ini3
-rw-r--r--docs/quick_tour/sqla_demo/setup.py79
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo.sqlitebin3072 -> 0 bytes
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/__init__.py18
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/alembic/env.py58
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/alembic/script.py.mako24
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/alembic/versions/README.txt1
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/models.py29
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/models/__init__.py77
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/models/meta.py16
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/models/mymodel.py18
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/pshell.py12
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/routes.py3
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/scripts/initialize_db.py48
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/scripts/initializedb.py37
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/static/favicon.icobin1406 -> 0 bytes
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/static/footerbg.pngbin333 -> 0 bytes
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/static/headerbg.pngbin203 -> 0 bytes
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/static/ie6.css8
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/static/middlebg.pngbin2797 -> 0 bytes
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/static/pylons.css372
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/static/pyramid-16x16.pngbin0 -> 1319 bytes
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/static/pyramid-small.pngbin7044 -> 0 bytes
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/static/pyramid.pngbin33055 -> 12901 bytes
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/static/theme.css154
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/static/transparent.gifbin49 -> 0 bytes
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/templates/404.jinja28
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/templates/layout.jinja264
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.jinja28
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.pt76
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/tests.py66
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/views/__init__.py0
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/views/default.py (renamed from docs/quick_tour/sqla_demo/sqla_demo/views.py)23
-rw-r--r--docs/quick_tour/sqla_demo/sqla_demo/views/notfound.py7
41 files changed, 708 insertions, 619 deletions
diff --git a/docs/quick_tour/sqla_demo/.coveragerc b/docs/quick_tour/sqla_demo/.coveragerc
new file mode 100644
index 000000000..918f8dea0
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/.coveragerc
@@ -0,0 +1,3 @@
+[run]
+source = sqla_demo
+omit = sqla_demo/test*
diff --git a/docs/quick_tour/sqla_demo/.gitignore b/docs/quick_tour/sqla_demo/.gitignore
new file mode 100644
index 000000000..1853d983c
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/.gitignore
@@ -0,0 +1,21 @@
+*.egg
+*.egg-info
+*.pyc
+*$py.class
+*~
+.coverage
+coverage.xml
+build/
+dist/
+.tox/
+nosetests.xml
+env*/
+tmp/
+Data.fs*
+*.sublime-project
+*.sublime-workspace
+.*.sw?
+.sw?
+.DS_Store
+coverage
+test
diff --git a/docs/quick_tour/sqla_demo/CHANGES.txt b/docs/quick_tour/sqla_demo/CHANGES.txt
index 35a34f332..14b902fd1 100644
--- a/docs/quick_tour/sqla_demo/CHANGES.txt
+++ b/docs/quick_tour/sqla_demo/CHANGES.txt
@@ -1,4 +1,4 @@
0.0
---
-- Initial version
+- Initial version.
diff --git a/docs/quick_tour/sqla_demo/MANIFEST.in b/docs/quick_tour/sqla_demo/MANIFEST.in
index a432577e9..e079655f9 100644
--- a/docs/quick_tour/sqla_demo/MANIFEST.in
+++ b/docs/quick_tour/sqla_demo/MANIFEST.in
@@ -1,2 +1,2 @@
include *.txt *.ini *.cfg *.rst
-recursive-include sqla_demo *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml
+recursive-include sqla_demo *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2
diff --git a/docs/quick_tour/sqla_demo/README.txt b/docs/quick_tour/sqla_demo/README.txt
index f35d3aec5..d00790492 100644
--- a/docs/quick_tour/sqla_demo/README.txt
+++ b/docs/quick_tour/sqla_demo/README.txt
@@ -1,14 +1,43 @@
-sqla_demo README
-==================
+sqla_demo
+=========
Getting Started
---------------
-- cd <directory containing this file>
+- Change directory into your newly created project.
-- $venv/bin/python setup.py develop
+ cd sqla_demo
-- $venv/bin/initialize_sqla_demo_db development.ini
+- Create a Python virtual environment.
-- $venv/bin/pserve development.ini
+ python3 -m venv env
+- Upgrade packaging tools.
+
+ env/bin/pip install --upgrade pip setuptools
+
+- Install the project in editable mode with its testing requirements.
+
+ env/bin/pip install -e ".[testing]"
+
+- Initialize and upgrade the database using Alembic.
+
+ - Generate your first revision.
+
+ env/bin/alembic -c development.ini revision --autogenerate -m "init"
+
+ - Upgrade to that revision.
+
+ env/bin/alembic -c development.ini upgrade head
+
+- Load default data into the database using a script.
+
+ env/bin/initialize_sqla_demo_db development.ini
+
+- Run your project's tests.
+
+ env/bin/pytest
+
+- Run your project.
+
+ env/bin/pserve development.ini
diff --git a/docs/quick_tour/sqla_demo/development.ini b/docs/quick_tour/sqla_demo/development.ini
index 174468abf..056a672e4 100644
--- a/docs/quick_tour/sqla_demo/development.ini
+++ b/docs/quick_tour/sqla_demo/development.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -13,26 +13,35 @@ pyramid.debug_routematch = false
pyramid.default_locale_name = en
pyramid.includes =
pyramid_debugtoolbar
- pyramid_tm
sqlalchemy.url = sqlite:///%(here)s/sqla_demo.sqlite
+retry.attempts = 3
+
# By default, the toolbar only appears for clients from IP addresses
# '127.0.0.1' and '::1'.
# debugtoolbar.hosts = 127.0.0.1 ::1
+[pshell]
+setup = sqla_demo.pshell.setup
+
###
# wsgi server configuration
###
+[alembic]
+# path to migration scripts
+script_location = sqla_demo/alembic
+file_template = %%(year)d%%(month).2d%%(day).2d_%%(rev)s
+# file_template = %%(rev)s_%%(slug)s
+
[server:main]
use = egg:waitress#main
-host = 0.0.0.0
-port = 6543
+listen = localhost:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
+# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
@@ -54,7 +63,7 @@ handlers =
qualname = sqla_demo
[logger_sqlalchemy]
-level = INFO
+level = WARN
handlers =
qualname = sqlalchemy.engine
# "level = INFO" logs SQL queries.
@@ -68,4 +77,4 @@ level = NOTSET
formatter = generic
[formatter_generic]
-format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
+format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s
diff --git a/docs/quick_tour/sqla_demo/production.ini b/docs/quick_tour/sqla_demo/production.ini
index dc0ba304f..fe7f946bd 100644
--- a/docs/quick_tour/sqla_demo/production.ini
+++ b/docs/quick_tour/sqla_demo/production.ini
@@ -1,6 +1,6 @@
###
# app configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
+# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/environment.html
###
[app:main]
@@ -11,19 +11,31 @@ pyramid.debug_authorization = false
pyramid.debug_notfound = false
pyramid.debug_routematch = false
pyramid.default_locale_name = en
-pyramid.includes =
- pyramid_tm
sqlalchemy.url = sqlite:///%(here)s/sqla_demo.sqlite
+retry.attempts = 3
+
+[pshell]
+setup = sqla_demo.pshell.setup
+
+###
+# wsgi server configuration
+###
+
+[alembic]
+# path to migration scripts
+script_location = sqla_demo/alembic
+file_template = %%(year)d%%(month).2d%%(day).2d_%%(rev)s
+# file_template = %%(rev)s_%%(slug)s
+
[server:main]
use = egg:waitress#main
-host = 0.0.0.0
-port = 6543
+listen = *:6543
###
# logging configuration
-# http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
+# https://docs.pylonsproject.org/projects/pyramid/en/latest/narr/logging.html
###
[loggers]
@@ -59,4 +71,4 @@ level = NOTSET
formatter = generic
[formatter_generic]
-format = %(asctime)s %(levelname)-5.5s [%(name)s][%(threadName)s] %(message)s
+format = %(asctime)s %(levelname)-5.5s [%(name)s:%(lineno)s][%(threadName)s] %(message)s
diff --git a/docs/quick_tour/sqla_demo/pytest.ini b/docs/quick_tour/sqla_demo/pytest.ini
new file mode 100644
index 000000000..b4b690a0f
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/pytest.ini
@@ -0,0 +1,3 @@
+[pytest]
+testpaths = sqla_demo
+python_files = test*.py
diff --git a/docs/quick_tour/sqla_demo/setup.py b/docs/quick_tour/sqla_demo/setup.py
index ac2eed035..76cd518ca 100644
--- a/docs/quick_tour/sqla_demo/setup.py
+++ b/docs/quick_tour/sqla_demo/setup.py
@@ -3,42 +3,59 @@ import os
from setuptools import setup, find_packages
here = os.path.abspath(os.path.dirname(__file__))
-README = open(os.path.join(here, 'README.txt')).read()
-CHANGES = open(os.path.join(here, 'CHANGES.txt')).read()
+with open(os.path.join(here, 'README.txt')) as f:
+ README = f.read()
+with open(os.path.join(here, 'CHANGES.txt')) as f:
+ CHANGES = f.read()
requires = [
- 'pyramid',
+ 'alembic',
+ 'plaster_pastedeploy',
+ 'pyramid >= 1.9',
+ 'pyramid_debugtoolbar',
+ 'pyramid_jinja2',
+ 'pyramid_retry',
+ 'pyramid_tm',
'SQLAlchemy',
'transaction',
- 'pyramid_tm',
- 'pyramid_debugtoolbar',
'zope.sqlalchemy',
'waitress',
- ]
+]
+
+tests_require = [
+ 'WebTest >= 1.3.1', # py3 compat
+ 'pytest>=3.7.4',
+ 'pytest-cov',
+]
-setup(name='sqla_demo',
- version='0.0',
- description='sqla_demo',
- long_description=README + '\n\n' + CHANGES,
- classifiers=[
- "Programming Language :: Python",
- "Framework :: Pyramid",
- "Topic :: Internet :: WWW/HTTP",
- "Topic :: Internet :: WWW/HTTP :: WSGI :: Application",
+setup(
+ name='sqla_demo',
+ version='0.0',
+ description='sqla_demo',
+ long_description=README + '\n\n' + CHANGES,
+ classifiers=[
+ 'Programming Language :: Python',
+ 'Framework :: Pyramid',
+ 'Topic :: Internet :: WWW/HTTP',
+ 'Topic :: Internet :: WWW/HTTP :: WSGI :: Application',
+ ],
+ author='',
+ author_email='',
+ url='',
+ keywords='web pyramid pylons',
+ packages=find_packages(),
+ include_package_data=True,
+ zip_safe=False,
+ extras_require={
+ 'testing': tests_require,
+ },
+ install_requires=requires,
+ entry_points={
+ 'paste.app_factory': [
+ 'main = sqla_demo:main',
+ ],
+ 'console_scripts': [
+ 'initialize_sqla_demo_db = sqla_demo.scripts.initialize_db:main',
],
- author='',
- author_email='',
- url='',
- keywords='web wsgi bfg pylons pyramid',
- packages=find_packages(),
- include_package_data=True,
- zip_safe=False,
- test_suite='sqla_demo',
- install_requires=requires,
- entry_points="""\
- [paste.app_factory]
- main = sqla_demo:main
- [console_scripts]
- initialize_sqla_demo_db = sqla_demo.scripts.initializedb:main
- """,
- )
+ },
+)
diff --git a/docs/quick_tour/sqla_demo/sqla_demo.sqlite b/docs/quick_tour/sqla_demo/sqla_demo.sqlite
deleted file mode 100644
index fa6adb104..000000000
--- a/docs/quick_tour/sqla_demo/sqla_demo.sqlite
+++ /dev/null
Binary files differ
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/__init__.py b/docs/quick_tour/sqla_demo/sqla_demo/__init__.py
index aac7c5e69..28bd1f80d 100644
--- a/docs/quick_tour/sqla_demo/sqla_demo/__init__.py
+++ b/docs/quick_tour/sqla_demo/sqla_demo/__init__.py
@@ -1,20 +1,12 @@
from pyramid.config import Configurator
-from sqlalchemy import engine_from_config
-
-from .models import (
- DBSession,
- Base,
- )
def main(global_config, **settings):
""" This function returns a Pyramid WSGI application.
"""
- engine = engine_from_config(settings, 'sqlalchemy.')
- DBSession.configure(bind=engine)
- Base.metadata.bind = engine
- config = Configurator(settings=settings)
- config.add_static_view('static', 'static', cache_max_age=3600)
- config.add_route('home', '/')
- config.scan()
+ with Configurator(settings=settings) as config:
+ config.include('pyramid_jinja2')
+ config.include('.models')
+ config.include('.routes')
+ config.scan()
return config.make_wsgi_app()
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/alembic/env.py b/docs/quick_tour/sqla_demo/sqla_demo/alembic/env.py
new file mode 100644
index 000000000..46ce86a4e
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/sqla_demo/alembic/env.py
@@ -0,0 +1,58 @@
+"""Pyramid bootstrap environment. """
+from alembic import context
+from pyramid.paster import get_appsettings, setup_logging
+from sqlalchemy import engine_from_config
+
+from sqla_demo.models.meta import Base
+
+config = context.config
+
+setup_logging(config.config_file_name)
+
+settings = get_appsettings(config.config_file_name)
+target_metadata = Base.metadata
+
+
+def run_migrations_offline():
+ """Run migrations in 'offline' mode.
+
+ This configures the context with just a URL
+ and not an Engine, though an Engine is acceptable
+ here as well. By skipping the Engine creation
+ we don't even need a DBAPI to be available.
+
+ Calls to context.execute() here emit the given string to the
+ script output.
+
+ """
+ context.configure(url=settings['sqlalchemy.url'])
+ with context.begin_transaction():
+ context.run_migrations()
+
+
+def run_migrations_online():
+ """Run migrations in 'online' mode.
+
+ In this scenario we need to create an Engine
+ and associate a connection with the context.
+
+ """
+ engine = engine_from_config(settings, prefix='sqlalchemy.')
+
+ connection = engine.connect()
+ context.configure(
+ connection=connection,
+ target_metadata=target_metadata
+ )
+
+ try:
+ with context.begin_transaction():
+ context.run_migrations()
+ finally:
+ connection.close()
+
+
+if context.is_offline_mode():
+ run_migrations_offline()
+else:
+ run_migrations_online()
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/alembic/script.py.mako b/docs/quick_tour/sqla_demo/sqla_demo/alembic/script.py.mako
new file mode 100644
index 000000000..2c0156303
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/sqla_demo/alembic/script.py.mako
@@ -0,0 +1,24 @@
+"""${message}
+
+Revision ID: ${up_revision}
+Revises: ${down_revision | comma,n}
+Create Date: ${create_date}
+
+"""
+from alembic import op
+import sqlalchemy as sa
+${imports if imports else ""}
+
+# revision identifiers, used by Alembic.
+revision = ${repr(up_revision)}
+down_revision = ${repr(down_revision)}
+branch_labels = ${repr(branch_labels)}
+depends_on = ${repr(depends_on)}
+
+
+def upgrade():
+ ${upgrades if upgrades else "pass"}
+
+
+def downgrade():
+ ${downgrades if downgrades else "pass"}
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/alembic/versions/README.txt b/docs/quick_tour/sqla_demo/sqla_demo/alembic/versions/README.txt
new file mode 100644
index 000000000..09ed32c8d
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/sqla_demo/alembic/versions/README.txt
@@ -0,0 +1 @@
+Placeholder for alembic versions \ No newline at end of file
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/models.py b/docs/quick_tour/sqla_demo/sqla_demo/models.py
deleted file mode 100644
index 3dfb40e58..000000000
--- a/docs/quick_tour/sqla_demo/sqla_demo/models.py
+++ /dev/null
@@ -1,29 +0,0 @@
-from sqlalchemy import (
- Column,
- Integer,
- Text,
- )
-
-from sqlalchemy.ext.declarative import declarative_base
-
-from sqlalchemy.orm import (
- scoped_session,
- sessionmaker,
- )
-
-from zope.sqlalchemy import ZopeTransactionExtension
-
-DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
-Base = declarative_base()
-
-# Start Sphinx Include
-class MyModel(Base):
- __tablename__ = 'models'
- id = Column(Integer, primary_key=True)
- name = Column(Text, unique=True)
- value = Column(Integer)
-
- def __init__(self, name, value):
- self.name = name
- self.value = value
- # End Sphinx Include
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/models/__init__.py b/docs/quick_tour/sqla_demo/sqla_demo/models/__init__.py
new file mode 100644
index 000000000..31aab9d26
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/sqla_demo/models/__init__.py
@@ -0,0 +1,77 @@
+from sqlalchemy import engine_from_config
+from sqlalchemy.orm import sessionmaker
+from sqlalchemy.orm import configure_mappers
+import zope.sqlalchemy
+
+# import or define all models here to ensure they are attached to the
+# Base.metadata prior to any initialization routines
+from .mymodel import MyModel # flake8: noqa
+
+# run configure_mappers after defining all of the models to ensure
+# all relationships can be setup
+configure_mappers()
+
+
+def get_engine(settings, prefix='sqlalchemy.'):
+ return engine_from_config(settings, prefix)
+
+
+def get_session_factory(engine):
+ factory = sessionmaker()
+ factory.configure(bind=engine)
+ return factory
+
+
+def get_tm_session(session_factory, transaction_manager):
+ """
+ Get a ``sqlalchemy.orm.Session`` instance backed by a transaction.
+
+ This function will hook the session to the transaction manager which
+ will take care of committing any changes.
+
+ - When using pyramid_tm it will automatically be committed or aborted
+ depending on whether an exception is raised.
+
+ - When using scripts you should wrap the session in a manager yourself.
+ For example::
+
+ import transaction
+
+ engine = get_engine(settings)
+ session_factory = get_session_factory(engine)
+ with transaction.manager:
+ dbsession = get_tm_session(session_factory, transaction.manager)
+
+ """
+ dbsession = session_factory()
+ zope.sqlalchemy.register(
+ dbsession, transaction_manager=transaction_manager)
+ return dbsession
+
+
+def includeme(config):
+ """
+ Initialize the model for a Pyramid app.
+
+ Activate this setup using ``config.include('sqla_demo.models')``.
+
+ """
+ settings = config.get_settings()
+ settings['tm.manager_hook'] = 'pyramid_tm.explicit_manager'
+
+ # use pyramid_tm to hook the transaction lifecycle to the request
+ config.include('pyramid_tm')
+
+ # use pyramid_retry to retry a request when transient exceptions occur
+ config.include('pyramid_retry')
+
+ session_factory = get_session_factory(get_engine(settings))
+ config.registry['dbsession_factory'] = session_factory
+
+ # make request.dbsession available for use in Pyramid
+ config.add_request_method(
+ # r.tm is the transaction manager used by pyramid_tm
+ lambda r: get_tm_session(session_factory, r.tm),
+ 'dbsession',
+ reify=True
+ )
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/models/meta.py b/docs/quick_tour/sqla_demo/sqla_demo/models/meta.py
new file mode 100644
index 000000000..02285b3ff
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/sqla_demo/models/meta.py
@@ -0,0 +1,16 @@
+from sqlalchemy.ext.declarative import declarative_base
+from sqlalchemy.schema import MetaData
+
+# Recommended naming convention used by Alembic, as various different database
+# providers will autogenerate vastly different names making migrations more
+# difficult. See: http://alembic.zzzcomputing.com/en/latest/naming.html
+NAMING_CONVENTION = {
+ "ix": "ix_%(column_0_label)s",
+ "uq": "uq_%(table_name)s_%(column_0_name)s",
+ "ck": "ck_%(table_name)s_%(constraint_name)s",
+ "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
+ "pk": "pk_%(table_name)s"
+}
+
+metadata = MetaData(naming_convention=NAMING_CONVENTION)
+Base = declarative_base(metadata=metadata)
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/models/mymodel.py b/docs/quick_tour/sqla_demo/sqla_demo/models/mymodel.py
new file mode 100644
index 000000000..d65a01a42
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/sqla_demo/models/mymodel.py
@@ -0,0 +1,18 @@
+from sqlalchemy import (
+ Column,
+ Index,
+ Integer,
+ Text,
+)
+
+from .meta import Base
+
+
+class MyModel(Base):
+ __tablename__ = 'models'
+ id = Column(Integer, primary_key=True)
+ name = Column(Text)
+ value = Column(Integer)
+
+
+Index('my_index', MyModel.name, unique=True, mysql_length=255)
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/pshell.py b/docs/quick_tour/sqla_demo/sqla_demo/pshell.py
new file mode 100644
index 000000000..108c04d5e
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/sqla_demo/pshell.py
@@ -0,0 +1,12 @@
+from . import models
+
+def setup(env):
+ request = env['request']
+
+ # start a transaction
+ request.tm.begin()
+
+ # inject some vars into the shell builtins
+ env['tm'] = request.tm
+ env['dbsession'] = request.dbsession
+ env['models'] = models
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/routes.py b/docs/quick_tour/sqla_demo/sqla_demo/routes.py
new file mode 100644
index 000000000..25504ad4d
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/sqla_demo/routes.py
@@ -0,0 +1,3 @@
+def includeme(config):
+ config.add_static_view('static', 'static', cache_max_age=3600)
+ config.add_route('home', '/')
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/scripts/initialize_db.py b/docs/quick_tour/sqla_demo/sqla_demo/scripts/initialize_db.py
new file mode 100644
index 000000000..c629d1780
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/sqla_demo/scripts/initialize_db.py
@@ -0,0 +1,48 @@
+import argparse
+import sys
+
+from pyramid.paster import bootstrap, setup_logging
+from sqlalchemy.exc import OperationalError
+
+from .. import models
+
+
+def setup_models(dbsession):
+ """
+ Add or update models / fixtures in the database.
+
+ """
+ model = models.mymodel.MyModel(name='one', value=1)
+ dbsession.add(model)
+
+
+def parse_args(argv):
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ 'config_uri',
+ help='Configuration file, e.g., development.ini',
+ )
+ return parser.parse_args(argv[1:])
+
+
+def main(argv=sys.argv):
+ args = parse_args(argv)
+ setup_logging(args.config_uri)
+ env = bootstrap(args.config_uri)
+
+ try:
+ with env['request'].tm:
+ dbsession = env['request'].dbsession
+ setup_models(dbsession)
+ except OperationalError:
+ print('''
+Pyramid is having a problem using your SQL database. The problem
+might be caused by one of the following things:
+
+1. You may need to initialize your database tables with `alembic`.
+ Check your README.txt for description and try to run it.
+
+2. Your database server may not be running. Check that the
+ database server referred to by the "sqlalchemy.url" setting in
+ your "development.ini" file is running.
+ ''')
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/scripts/initializedb.py b/docs/quick_tour/sqla_demo/sqla_demo/scripts/initializedb.py
deleted file mode 100644
index 66feb3008..000000000
--- a/docs/quick_tour/sqla_demo/sqla_demo/scripts/initializedb.py
+++ /dev/null
@@ -1,37 +0,0 @@
-import os
-import sys
-import transaction
-
-from sqlalchemy import engine_from_config
-
-from pyramid.paster import (
- get_appsettings,
- setup_logging,
- )
-
-from ..models import (
- DBSession,
- MyModel,
- Base,
- )
-
-
-def usage(argv):
- cmd = os.path.basename(argv[0])
- print('usage: %s <config_uri>\n'
- '(example: "%s development.ini")' % (cmd, cmd))
- sys.exit(1)
-
-
-def main(argv=sys.argv):
- if len(argv) != 2:
- usage(argv)
- config_uri = argv[1]
- setup_logging(config_uri)
- settings = get_appsettings(config_uri)
- engine = engine_from_config(settings, 'sqlalchemy.')
- DBSession.configure(bind=engine)
- Base.metadata.create_all(engine)
- with transaction.manager:
- model = MyModel(name='one', value=1)
- DBSession.add(model)
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/favicon.ico b/docs/quick_tour/sqla_demo/sqla_demo/static/favicon.ico
deleted file mode 100644
index 71f837c9e..000000000
--- a/docs/quick_tour/sqla_demo/sqla_demo/static/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/footerbg.png b/docs/quick_tour/sqla_demo/sqla_demo/static/footerbg.png
deleted file mode 100644
index 1fbc873da..000000000
--- a/docs/quick_tour/sqla_demo/sqla_demo/static/footerbg.png
+++ /dev/null
Binary files differ
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/headerbg.png b/docs/quick_tour/sqla_demo/sqla_demo/static/headerbg.png
deleted file mode 100644
index 0596f2020..000000000
--- a/docs/quick_tour/sqla_demo/sqla_demo/static/headerbg.png
+++ /dev/null
Binary files differ
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/ie6.css b/docs/quick_tour/sqla_demo/sqla_demo/static/ie6.css
deleted file mode 100644
index b7c8493d8..000000000
--- a/docs/quick_tour/sqla_demo/sqla_demo/static/ie6.css
+++ /dev/null
@@ -1,8 +0,0 @@
-* html img,
-* html .png{position:relative;behavior:expression((this.runtimeStyle.behavior="none")&&(this.pngSet?this.pngSet=true:(this.nodeName == "IMG" && this.src.toLowerCase().indexOf('.png')>-1?(this.runtimeStyle.backgroundImage = "none",
-this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.src + "',sizingMethod='image')",
-this.src = "static/transparent.gif"):(this.origBg = this.origBg? this.origBg :this.currentStyle.backgroundImage.toString().replace('url("','').replace('")',''),
-this.runtimeStyle.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + this.origBg + "',sizingMethod='crop')",
-this.runtimeStyle.backgroundImage = "none")),this.pngSet=true)
-);}
-#wrap{display:table;height:100%}
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/middlebg.png b/docs/quick_tour/sqla_demo/sqla_demo/static/middlebg.png
deleted file mode 100644
index 2369cfb7d..000000000
--- a/docs/quick_tour/sqla_demo/sqla_demo/static/middlebg.png
+++ /dev/null
Binary files differ
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/pylons.css b/docs/quick_tour/sqla_demo/sqla_demo/static/pylons.css
deleted file mode 100644
index 4b1c017cd..000000000
--- a/docs/quick_tour/sqla_demo/sqla_demo/static/pylons.css
+++ /dev/null
@@ -1,372 +0,0 @@
-html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td
-{
- margin: 0;
- padding: 0;
- border: 0;
- outline: 0;
- font-size: 100%; /* 16px */
- vertical-align: baseline;
- background: transparent;
-}
-
-body
-{
- line-height: 1;
-}
-
-ol, ul
-{
- list-style: none;
-}
-
-blockquote, q
-{
- quotes: none;
-}
-
-blockquote:before, blockquote:after, q:before, q:after
-{
- content: '';
- content: none;
-}
-
-:focus
-{
- outline: 0;
-}
-
-ins
-{
- text-decoration: none;
-}
-
-del
-{
- text-decoration: line-through;
-}
-
-table
-{
- border-collapse: collapse;
- border-spacing: 0;
-}
-
-sub
-{
- vertical-align: sub;
- font-size: smaller;
- line-height: normal;
-}
-
-sup
-{
- vertical-align: super;
- font-size: smaller;
- line-height: normal;
-}
-
-ul, menu, dir
-{
- display: block;
- list-style-type: disc;
- margin: 1em 0;
- padding-left: 40px;
-}
-
-ol
-{
- display: block;
- list-style-type: decimal-leading-zero;
- margin: 1em 0;
- padding-left: 40px;
-}
-
-li
-{
- display: list-item;
-}
-
-ul ul, ul ol, ul dir, ul menu, ul dl, ol ul, ol ol, ol dir, ol menu, ol dl, dir ul, dir ol, dir dir, dir menu, dir dl, menu ul, menu ol, menu dir, menu menu, menu dl, dl ul, dl ol, dl dir, dl menu, dl dl
-{
- margin-top: 0;
- margin-bottom: 0;
-}
-
-ol ul, ul ul, menu ul, dir ul, ol menu, ul menu, menu menu, dir menu, ol dir, ul dir, menu dir, dir dir
-{
- list-style-type: circle;
-}
-
-ol ol ul, ol ul ul, ol menu ul, ol dir ul, ol ol menu, ol ul menu, ol menu menu, ol dir menu, ol ol dir, ol ul dir, ol menu dir, ol dir dir, ul ol ul, ul ul ul, ul menu ul, ul dir ul, ul ol menu, ul ul menu, ul menu menu, ul dir menu, ul ol dir, ul ul dir, ul menu dir, ul dir dir, menu ol ul, menu ul ul, menu menu ul, menu dir ul, menu ol menu, menu ul menu, menu menu menu, menu dir menu, menu ol dir, menu ul dir, menu menu dir, menu dir dir, dir ol ul, dir ul ul, dir menu ul, dir dir ul, dir ol menu, dir ul menu, dir menu menu, dir dir menu, dir ol dir, dir ul dir, dir menu dir, dir dir dir
-{
- list-style-type: square;
-}
-
-.hidden
-{
- display: none;
-}
-
-p
-{
- line-height: 1.5em;
-}
-
-h1
-{
- font-size: 1.75em;
- line-height: 1.7em;
- font-family: helvetica, verdana;
-}
-
-h2
-{
- font-size: 1.5em;
- line-height: 1.7em;
- font-family: helvetica, verdana;
-}
-
-h3
-{
- font-size: 1.25em;
- line-height: 1.7em;
- font-family: helvetica, verdana;
-}
-
-h4
-{
- font-size: 1em;
- line-height: 1.7em;
- font-family: helvetica, verdana;
-}
-
-html, body
-{
- width: 100%;
- height: 100%;
-}
-
-body
-{
- margin: 0;
- padding: 0;
- background-color: #fff;
- position: relative;
- font: 16px/24px NobileRegular, "Lucida Grande", Lucida, Verdana, sans-serif;
-}
-
-a
-{
- color: #1b61d6;
- text-decoration: none;
-}
-
-a:hover
-{
- color: #e88f00;
- text-decoration: underline;
-}
-
-body h1, body h2, body h3, body h4, body h5, body h6
-{
- font-family: NeutonRegular, "Lucida Grande", Lucida, Verdana, sans-serif;
- font-weight: 400;
- color: #373839;
- font-style: normal;
-}
-
-#wrap
-{
- min-height: 100%;
-}
-
-#header, #footer
-{
- width: 100%;
- color: #fff;
- height: 40px;
- position: absolute;
- text-align: center;
- line-height: 40px;
- overflow: hidden;
- font-size: 12px;
- vertical-align: middle;
-}
-
-#header
-{
- background: #000;
- top: 0;
- font-size: 14px;
-}
-
-#footer
-{
- bottom: 0;
- background: #000 url(footerbg.png) repeat-x 0 top;
- position: relative;
- margin-top: -40px;
- clear: both;
-}
-
-.header, .footer
-{
- width: 750px;
- margin-right: auto;
- margin-left: auto;
-}
-
-.wrapper
-{
- width: 100%;
-}
-
-#top, #top-small, #bottom
-{
- width: 100%;
-}
-
-#top
-{
- color: #000;
- height: 230px;
- background: #fff url(headerbg.png) repeat-x 0 top;
- position: relative;
-}
-
-#top-small
-{
- color: #000;
- height: 60px;
- background: #fff url(headerbg.png) repeat-x 0 top;
- position: relative;
-}
-
-#bottom
-{
- color: #222;
- background-color: #fff;
-}
-
-.top, .top-small, .middle, .bottom
-{
- width: 750px;
- margin-right: auto;
- margin-left: auto;
-}
-
-.top
-{
- padding-top: 40px;
-}
-
-.top-small
-{
- padding-top: 10px;
-}
-
-#middle
-{
- width: 100%;
- height: 100px;
- background: url(middlebg.png) repeat-x;
- border-top: 2px solid #fff;
- border-bottom: 2px solid #b2b2b2;
-}
-
-.app-welcome
-{
- margin-top: 25px;
-}
-
-.app-name
-{
- color: #000;
- font-weight: 700;
-}
-
-.bottom
-{
- padding-top: 50px;
-}
-
-#left
-{
- width: 350px;
- float: left;
- padding-right: 25px;
-}
-
-#right
-{
- width: 350px;
- float: right;
- padding-left: 25px;
-}
-
-.align-left
-{
- text-align: left;
-}
-
-.align-right
-{
- text-align: right;
-}
-
-.align-center
-{
- text-align: center;
-}
-
-ul.links
-{
- margin: 0;
- padding: 0;
-}
-
-ul.links li
-{
- list-style-type: none;
- font-size: 14px;
-}
-
-form
-{
- border-style: none;
-}
-
-fieldset
-{
- border-style: none;
-}
-
-input
-{
- color: #222;
- border: 1px solid #ccc;
- font-family: sans-serif;
- font-size: 12px;
- line-height: 16px;
-}
-
-input[type=text], input[type=password]
-{
- width: 205px;
-}
-
-input[type=submit]
-{
- background-color: #ddd;
- font-weight: 700;
-}
-
-/*Opera Fix*/
-body:before
-{
- content: "";
- height: 100%;
- float: left;
- width: 0;
- margin-top: -32767px;
-}
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/pyramid-16x16.png b/docs/quick_tour/sqla_demo/sqla_demo/static/pyramid-16x16.png
new file mode 100644
index 000000000..979203112
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/sqla_demo/static/pyramid-16x16.png
Binary files differ
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/pyramid-small.png b/docs/quick_tour/sqla_demo/sqla_demo/static/pyramid-small.png
deleted file mode 100644
index a5bc0ade7..000000000
--- a/docs/quick_tour/sqla_demo/sqla_demo/static/pyramid-small.png
+++ /dev/null
Binary files differ
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/pyramid.png b/docs/quick_tour/sqla_demo/sqla_demo/static/pyramid.png
index 347e05549..4ab837be9 100644
--- a/docs/quick_tour/sqla_demo/sqla_demo/static/pyramid.png
+++ b/docs/quick_tour/sqla_demo/sqla_demo/static/pyramid.png
Binary files differ
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/theme.css b/docs/quick_tour/sqla_demo/sqla_demo/static/theme.css
new file mode 100644
index 000000000..0f4b1a4d4
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/sqla_demo/static/theme.css
@@ -0,0 +1,154 @@
+@import url(//fonts.googleapis.com/css?family=Open+Sans:300,400,600,700);
+body {
+ font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-weight: 300;
+ color: #ffffff;
+ background: #bc2131;
+}
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-weight: 300;
+}
+p {
+ font-weight: 300;
+}
+.font-normal {
+ font-weight: 400;
+}
+.font-semi-bold {
+ font-weight: 600;
+}
+.font-bold {
+ font-weight: 700;
+}
+.starter-template {
+ margin-top: 250px;
+}
+.starter-template .content {
+ margin-left: 10px;
+}
+.starter-template .content h1 {
+ margin-top: 10px;
+ font-size: 60px;
+}
+.starter-template .content h1 .smaller {
+ font-size: 40px;
+ color: #f2b7bd;
+}
+.starter-template .content .lead {
+ font-size: 25px;
+ color: #f2b7bd;
+}
+.starter-template .content .lead .font-normal {
+ color: #ffffff;
+}
+.starter-template .links {
+ float: right;
+ right: 0;
+ margin-top: 125px;
+}
+.starter-template .links ul {
+ display: block;
+ padding: 0;
+ margin: 0;
+}
+.starter-template .links ul li {
+ list-style: none;
+ display: inline;
+ margin: 0 10px;
+}
+.starter-template .links ul li:first-child {
+ margin-left: 0;
+}
+.starter-template .links ul li:last-child {
+ margin-right: 0;
+}
+.starter-template .links ul li.current-version {
+ color: #f2b7bd;
+ font-weight: 400;
+}
+.starter-template .links ul li a, a {
+ color: #f2b7bd;
+ text-decoration: underline;
+}
+.starter-template .links ul li a:hover, a:hover {
+ color: #ffffff;
+ text-decoration: underline;
+}
+.starter-template .links ul li .icon-muted {
+ color: #eb8b95;
+ margin-right: 5px;
+}
+.starter-template .links ul li:hover .icon-muted {
+ color: #ffffff;
+}
+.starter-template .copyright {
+ margin-top: 10px;
+ font-size: 0.9em;
+ color: #f2b7bd;
+ text-transform: lowercase;
+ float: right;
+ right: 0;
+}
+@media (max-width: 1199px) {
+ .starter-template .content h1 {
+ font-size: 45px;
+ }
+ .starter-template .content h1 .smaller {
+ font-size: 30px;
+ }
+ .starter-template .content .lead {
+ font-size: 20px;
+ }
+}
+@media (max-width: 991px) {
+ .starter-template {
+ margin-top: 0;
+ }
+ .starter-template .logo {
+ margin: 40px auto;
+ }
+ .starter-template .content {
+ margin-left: 0;
+ text-align: center;
+ }
+ .starter-template .content h1 {
+ margin-bottom: 20px;
+ }
+ .starter-template .links {
+ float: none;
+ text-align: center;
+ margin-top: 60px;
+ }
+ .starter-template .copyright {
+ float: none;
+ text-align: center;
+ }
+}
+@media (max-width: 767px) {
+ .starter-template .content h1 .smaller {
+ font-size: 25px;
+ display: block;
+ }
+ .starter-template .content .lead {
+ font-size: 16px;
+ }
+ .starter-template .links {
+ margin-top: 40px;
+ }
+ .starter-template .links ul li {
+ display: block;
+ margin: 0;
+ }
+ .starter-template .links ul li .icon-muted {
+ display: none;
+ }
+ .starter-template .copyright {
+ margin-top: 20px;
+ }
+}
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/static/transparent.gif b/docs/quick_tour/sqla_demo/sqla_demo/static/transparent.gif
deleted file mode 100644
index 0341802e5..000000000
--- a/docs/quick_tour/sqla_demo/sqla_demo/static/transparent.gif
+++ /dev/null
Binary files differ
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/templates/404.jinja2 b/docs/quick_tour/sqla_demo/sqla_demo/templates/404.jinja2
new file mode 100644
index 000000000..1917f83c7
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/sqla_demo/templates/404.jinja2
@@ -0,0 +1,8 @@
+{% extends "layout.jinja2" %}
+
+{% block content %}
+<div class="content">
+ <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy scaffold</span></h1>
+ <p class="lead"><span class="font-semi-bold">404</span> Page Not Found</p>
+</div>
+{% endblock content %}
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/templates/layout.jinja2 b/docs/quick_tour/sqla_demo/sqla_demo/templates/layout.jinja2
new file mode 100644
index 000000000..107691acf
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/sqla_demo/templates/layout.jinja2
@@ -0,0 +1,64 @@
+<!DOCTYPE html>
+<html lang="{{request.locale_name}}">
+ <head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <meta name="description" content="pyramid web application">
+ <meta name="author" content="Pylons Project">
+ <link rel="shortcut icon" href="{{request.static_url('sqla_demo:static/pyramid-16x16.png')}}">
+
+ <title>Cookiecutter Alchemy project for the Pyramid Web Framework</title>
+
+ <!-- Bootstrap core CSS -->
+ <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
+
+ <!-- Custom styles for this scaffold -->
+ <link href="{{request.static_url('sqla_demo:static/theme.css')}}" rel="stylesheet">
+
+ <!-- HTML5 shiv and Respond.js IE8 support of HTML5 elements and media queries -->
+ <!--[if lt IE 9]>
+ <script src="//oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js" integrity="sha384-0s5Pv64cNZJieYFkXYOTId2HMA2Lfb6q2nAcx2n0RTLUnCAoTTsS0nKEO27XyKcY" crossorigin="anonymous"></script>
+ <script src="//oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js" integrity="sha384-ZoaMbDF+4LeFxg6WdScQ9nnR1QC2MIRxA1O9KWEXQwns1G8UNyIEZIQidzb0T1fo" crossorigin="anonymous"></script>
+ <![endif]-->
+ </head>
+
+ <body>
+
+ <div class="starter-template">
+ <div class="container">
+ <div class="row">
+ <div class="col-md-2">
+ <img class="logo img-responsive" src="{{request.static_url('sqla_demo:static/pyramid.png') }}" alt="pyramid web framework">
+ </div>
+ <div class="col-md-10">
+ {% block content %}
+ <p>No content</p>
+ {% endblock content %}
+ </div>
+ </div>
+ <div class="row">
+ <div class="links">
+ <ul>
+ <li><i class="glyphicon glyphicon-cog icon-muted"></i><a href="https://github.com/Pylons/pyramid">Github Project</a></li>
+ <li><i class="glyphicon glyphicon-globe icon-muted"></i><a href="https://webchat.freenode.net/?channels=pyramid">IRC Channel</a></li>
+ <li><i class="glyphicon glyphicon-home icon-muted"></i><a href="https://pylonsproject.org">Pylons Project</a></li>
+ </ul>
+ </div>
+ </div>
+ <div class="row">
+ <div class="copyright">
+ Copyright &copy; Pylons Project
+ </div>
+ </div>
+ </div>
+ </div>
+
+
+ <!-- Bootstrap core JavaScript
+ ================================================== -->
+ <!-- Placed at the end of the document so the pages load faster -->
+ <script src="//code.jquery.com/jquery-1.12.4.min.js" integrity="sha256-ZosEbRLbNQzLpnKIkEdrPv7lOy9C27hHQ+Xp8a4MxAQ=" crossorigin="anonymous"></script>
+ <script src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
+ </body>
+</html>
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.jinja2 b/docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.jinja2
new file mode 100644
index 000000000..d8b0a4232
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.jinja2
@@ -0,0 +1,8 @@
+{% extends "layout.jinja2" %}
+
+{% block content %}
+<div class="content">
+ <h1><span class="font-semi-bold">Pyramid</span> <span class="smaller">Alchemy project</span></h1>
+ <p class="lead">Welcome to <span class="font-normal">{{project}}</span>, a&nbsp;Pyramid application generated&nbsp;by<br><span class="font-normal">Cookiecutter</span>.</p>
+</div>
+{% endblock content %} \ No newline at end of file
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.pt b/docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.pt
deleted file mode 100644
index 321c0f5fb..000000000
--- a/docs/quick_tour/sqla_demo/sqla_demo/templates/mytemplate.pt
+++ /dev/null
@@ -1,76 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" xmlns:tal="http://xml.zope.org/namespaces/tal">
-<head>
- <title>The Pyramid Web Framework</title>
- <meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/>
- <meta name="keywords" content="python web application" />
- <meta name="description" content="pyramid web application" />
- <link rel="shortcut icon" href="${request.static_url('sqla_demo:static/favicon.ico')}" />
- <link rel="stylesheet" href="${request.static_url('sqla_demo:static/pylons.css')}" type="text/css" media="screen" charset="utf-8" />
- <link rel="stylesheet" href="http://static.pylonsproject.org/fonts/nobile/stylesheet.css" media="screen" />
- <link rel="stylesheet" href="http://static.pylonsproject.org/fonts/neuton/stylesheet.css" media="screen" />
- <!--[if lte IE 6]>
- <link rel="stylesheet" href="${request.static_url('sqla_demo:static/ie6.css')}" type="text/css" media="screen" charset="utf-8" />
- <![endif]-->
-</head>
-<body>
- <div id="wrap">
- <div id="top">
- <div class="top align-center">
- <div><img src="${request.static_url('sqla_demo:static/pyramid.png')}" width="750" height="169" alt="pyramid"/></div>
- </div>
- </div>
- <div id="middle">
- <div class="middle align-center">
- <p class="app-welcome">
- Welcome to <span class="app-name">${project}</span>, an application generated by<br/>
- the Pyramid web framework.
- </p>
- </div>
- </div>
- <div id="bottom">
- <div class="bottom">
- <div id="left" class="align-right">
- <h2>Search documentation</h2>
- <form method="get" action="http://docs.pylonsproject.org/projects/pyramid/en/1.4-branch/search.html">
- <input type="text" id="q" name="q" value="" />
- <input type="submit" id="x" value="Go" />
- </form>
- </div>
- <div id="right" class="align-left">
- <h2>Pyramid links</h2>
- <ul class="links">
- <li>
- <a href="http://pylonsproject.org">Pylons Website</a>
- </li>
- <li>
- <a href="http://docs.pylonsproject.org/projects/pyramid/en/1.4-branch/#narrative-documentation">Narrative Documentation</a>
- </li>
- <li>
- <a href="http://docs.pylonsproject.org/projects/pyramid/en/1.4-branch/#reference-material">API Documentation</a>
- </li>
- <li>
- <a href="http://docs.pylonsproject.org/projects/pyramid/en/1.4-branch/#tutorials">Tutorials</a>
- </li>
- <li>
- <a href="http://docs.pylonsproject.org/projects/pyramid/en/1.4-branch/#detailed-change-history">Change History</a>
- </li>
- <li>
- <a href="http://docs.pylonsproject.org/projects/pyramid/en/1.4-branch/#sample-applications">Sample Applications</a>
- </li>
- <li>
- <a href="http://docs.pylonsproject.org/projects/pyramid/en/1.4-branch/#support-and-development">Support and Development</a>
- </li>
- <li>
- <a href="irc://irc.freenode.net#pyramid">IRC Channel</a>
- </li>
- </ul>
- </div>
- </div>
- </div>
- </div>
- <div id="footer">
- <div class="footer">&copy; Copyright 2008-2012, Agendaless Consulting.</div>
- </div>
-</body>
-</html>
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/tests.py b/docs/quick_tour/sqla_demo/sqla_demo/tests.py
index 6fef6d695..6db538ffd 100644
--- a/docs/quick_tour/sqla_demo/sqla_demo/tests.py
+++ b/docs/quick_tour/sqla_demo/sqla_demo/tests.py
@@ -3,31 +3,63 @@ import transaction
from pyramid import testing
-from .models import DBSession
+def dummy_request(dbsession):
+ return testing.DummyRequest(dbsession=dbsession)
-class TestMyView(unittest.TestCase):
+
+class BaseTest(unittest.TestCase):
def setUp(self):
- self.config = testing.setUp()
- from sqlalchemy import create_engine
- engine = create_engine('sqlite://')
+ self.config = testing.setUp(settings={
+ 'sqlalchemy.url': 'sqlite:///:memory:'
+ })
+ self.config.include('.models')
+ settings = self.config.get_settings()
+
from .models import (
- Base,
- MyModel,
+ get_engine,
+ get_session_factory,
+ get_tm_session,
)
- DBSession.configure(bind=engine)
- Base.metadata.create_all(engine)
- with transaction.manager:
- model = MyModel(name='one', value=55)
- DBSession.add(model)
+
+ self.engine = get_engine(settings)
+ session_factory = get_session_factory(self.engine)
+
+ self.session = get_tm_session(session_factory, transaction.manager)
+
+ def init_database(self):
+ from .models.meta import Base
+ Base.metadata.create_all(self.engine)
def tearDown(self):
- DBSession.remove()
+ from .models.meta import Base
+
testing.tearDown()
+ transaction.abort()
+ Base.metadata.drop_all(self.engine)
+
+
+class TestMyViewSuccessCondition(BaseTest):
- def test_it(self):
- from .views import my_view
- request = testing.DummyRequest()
- info = my_view(request)
+ def setUp(self):
+ super(TestMyViewSuccessCondition, self).setUp()
+ self.init_database()
+
+ from .models import MyModel
+
+ model = MyModel(name='one', value=55)
+ self.session.add(model)
+
+ def test_passing_view(self):
+ from .views.default import my_view
+ info = my_view(dummy_request(self.session))
self.assertEqual(info['one'].name, 'one')
self.assertEqual(info['project'], 'sqla_demo')
+
+
+class TestMyViewFailureCondition(BaseTest):
+
+ def test_failing_view(self):
+ from .views.default import my_view
+ info = my_view(dummy_request(self.session))
+ self.assertEqual(info.status_int, 500)
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/views/__init__.py b/docs/quick_tour/sqla_demo/sqla_demo/views/__init__.py
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/sqla_demo/views/__init__.py
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/views.py b/docs/quick_tour/sqla_demo/sqla_demo/views/default.py
index 768a7e42e..f7ad4c8f2 100644
--- a/docs/quick_tour/sqla_demo/sqla_demo/views.py
+++ b/docs/quick_tour/sqla_demo/sqla_demo/views/default.py
@@ -3,29 +3,25 @@ from pyramid.view import view_config
from sqlalchemy.exc import DBAPIError
-from .models import (
- DBSession,
- MyModel,
- )
+from .. import models
-@view_config(route_name='home', renderer='templates/mytemplate.pt')
+@view_config(route_name='home', renderer='../templates/mytemplate.jinja2')
def my_view(request):
try:
- # Start Sphinx Include
- one = DBSession.query(MyModel).filter(MyModel.name == 'one').first()
- # End Sphinx Include
+ query = request.dbsession.query(models.MyModel)
+ one = query.filter(models.MyModel.name == 'one').first()
except DBAPIError:
- return Response(conn_err_msg, content_type='text/plain', status_int=500)
+ return Response(db_err_msg, content_type='text/plain', status=500)
return {'one': one, 'project': 'sqla_demo'}
-conn_err_msg = """\
+
+db_err_msg = """\
Pyramid is having a problem using your SQL database. The problem
might be caused by one of the following things:
-1. You may need to run the "initialize_sqla_demo_db" script
- to initialize your database tables. Check your virtual
- environment's "bin" directory for this script and try to run it.
+1. You may need to initialize your database tables with `alembic`.
+ Check your README.txt for description and try to run it.
2. Your database server may not be running. Check that the
database server referred to by the "sqlalchemy.url" setting in
@@ -34,4 +30,3 @@ might be caused by one of the following things:
After you fix the problem, please restart the Pyramid application to
try it again.
"""
-
diff --git a/docs/quick_tour/sqla_demo/sqla_demo/views/notfound.py b/docs/quick_tour/sqla_demo/sqla_demo/views/notfound.py
new file mode 100644
index 000000000..69d6e2804
--- /dev/null
+++ b/docs/quick_tour/sqla_demo/sqla_demo/views/notfound.py
@@ -0,0 +1,7 @@
+from pyramid.view import notfound_view_config
+
+
+@notfound_view_config(renderer='../templates/404.jinja2')
+def notfound_view(request):
+ request.response.status = 404
+ return {}