From 63f24316b5b042d1cb6fe01528d800fdd5281f0a Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 22 Jun 2018 17:59:53 -0700 Subject: Update source files for installation step with new alembic support --- docs/tutorials/wiki2/src/installation/.gitignore | 21 ++++++++ docs/tutorials/wiki2/src/installation/README.txt | 14 +++++- .../wiki2/src/installation/development.ini | 6 +++ .../wiki2/src/installation/production.ini | 6 +++ docs/tutorials/wiki2/src/installation/pytest.ini | 2 +- docs/tutorials/wiki2/src/installation/setup.py | 3 +- .../wiki2/src/installation/tutorial/alembic/env.py | 58 ++++++++++++++++++++++ .../installation/tutorial/alembic/script.py.mako | 24 +++++++++ .../tutorial/alembic/versions/README.txt | 1 + .../installation/tutorial/scripts/initialize_db.py | 44 ++++++++++++++++ .../installation/tutorial/scripts/initializedb.py | 45 ----------------- .../tutorial/templates/mytemplate.jinja2 | 2 +- .../src/installation/tutorial/views/default.py | 5 +- 13 files changed, 178 insertions(+), 53 deletions(-) create mode 100644 docs/tutorials/wiki2/src/installation/.gitignore create mode 100644 docs/tutorials/wiki2/src/installation/tutorial/alembic/env.py create mode 100644 docs/tutorials/wiki2/src/installation/tutorial/alembic/script.py.mako create mode 100644 docs/tutorials/wiki2/src/installation/tutorial/alembic/versions/README.txt create mode 100644 docs/tutorials/wiki2/src/installation/tutorial/scripts/initialize_db.py delete mode 100644 docs/tutorials/wiki2/src/installation/tutorial/scripts/initializedb.py (limited to 'docs/tutorials/wiki2/src') diff --git a/docs/tutorials/wiki2/src/installation/.gitignore b/docs/tutorials/wiki2/src/installation/.gitignore new file mode 100644 index 000000000..1853d983c --- /dev/null +++ b/docs/tutorials/wiki2/src/installation/.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/tutorials/wiki2/src/installation/README.txt b/docs/tutorials/wiki2/src/installation/README.txt index 7b33da610..6d2df698e 100644 --- a/docs/tutorials/wiki2/src/installation/README.txt +++ b/docs/tutorials/wiki2/src/installation/README.txt @@ -20,9 +20,19 @@ Getting Started env/bin/pip install -e ".[testing]" -- Configure the database. +- Initialize the database using Alembic. - env/bin/initialize_tutorial_db development.ini + - 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. + + env/bin/initialize_tutorial_db development.ini - Run your project's tests. diff --git a/docs/tutorials/wiki2/src/installation/development.ini b/docs/tutorials/wiki2/src/installation/development.ini index 4a67896b2..ee050c0ea 100644 --- a/docs/tutorials/wiki2/src/installation/development.ini +++ b/docs/tutorials/wiki2/src/installation/development.ini @@ -26,6 +26,12 @@ retry.attempts = 3 # wsgi server configuration ### +[alembic] +# path to migration scripts +script_location = tutorial/alembic +file_template = %%(year)d%%(month).2d%%(day).2d_%%(rev)s +# file_template = %%(rev)s_%%(slug)s + [server:main] use = egg:waitress#main listen = localhost:6543 diff --git a/docs/tutorials/wiki2/src/installation/production.ini b/docs/tutorials/wiki2/src/installation/production.ini index a28e47a83..91d0f5ddb 100644 --- a/docs/tutorials/wiki2/src/installation/production.ini +++ b/docs/tutorials/wiki2/src/installation/production.ini @@ -20,6 +20,12 @@ retry.attempts = 3 # wsgi server configuration ### +[alembic] +# path to migration scripts +script_location = tutorial/alembic +file_template = %%(year)d%%(month).2d%%(day).2d_%%(rev)s +# file_template = %%(rev)s_%%(slug)s + [server:main] use = egg:waitress#main listen = *:6543 diff --git a/docs/tutorials/wiki2/src/installation/pytest.ini b/docs/tutorials/wiki2/src/installation/pytest.ini index 8b76bc410..a3489cdf8 100644 --- a/docs/tutorials/wiki2/src/installation/pytest.ini +++ b/docs/tutorials/wiki2/src/installation/pytest.ini @@ -1,3 +1,3 @@ [pytest] testpaths = tutorial -python_files = *.py +python_files = test*.py diff --git a/docs/tutorials/wiki2/src/installation/setup.py b/docs/tutorials/wiki2/src/installation/setup.py index 9fc5519a5..1638ef28e 100644 --- a/docs/tutorials/wiki2/src/installation/setup.py +++ b/docs/tutorials/wiki2/src/installation/setup.py @@ -9,6 +9,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: CHANGES = f.read() requires = [ + 'alembic', 'plaster_pastedeploy', 'pyramid >= 1.9a', 'pyramid_debugtoolbar', @@ -54,7 +55,7 @@ setup( 'main = tutorial:main', ], 'console_scripts': [ - 'initialize_tutorial_db = tutorial.scripts.initializedb:main', + 'initialize_tutorial_db = tutorial.scripts.initialize_db:main', ], }, ) diff --git a/docs/tutorials/wiki2/src/installation/tutorial/alembic/env.py b/docs/tutorials/wiki2/src/installation/tutorial/alembic/env.py new file mode 100644 index 000000000..730785899 --- /dev/null +++ b/docs/tutorials/wiki2/src/installation/tutorial/alembic/env.py @@ -0,0 +1,58 @@ +"""Pyramid bootstrap environment. """ +from alembic import context +from pyramid.paster import get_appsettings, setup_logging + +from tutorial.models import get_engine +from tutorial.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 = get_engine(settings) + + 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/tutorials/wiki2/src/installation/tutorial/alembic/script.py.mako b/docs/tutorials/wiki2/src/installation/tutorial/alembic/script.py.mako new file mode 100644 index 000000000..2c0156303 --- /dev/null +++ b/docs/tutorials/wiki2/src/installation/tutorial/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/tutorials/wiki2/src/installation/tutorial/alembic/versions/README.txt b/docs/tutorials/wiki2/src/installation/tutorial/alembic/versions/README.txt new file mode 100644 index 000000000..09ed32c8d --- /dev/null +++ b/docs/tutorials/wiki2/src/installation/tutorial/alembic/versions/README.txt @@ -0,0 +1 @@ +Placeholder for alembic versions \ No newline at end of file diff --git a/docs/tutorials/wiki2/src/installation/tutorial/scripts/initialize_db.py b/docs/tutorials/wiki2/src/installation/tutorial/scripts/initialize_db.py new file mode 100644 index 000000000..5b129e761 --- /dev/null +++ b/docs/tutorials/wiki2/src/installation/tutorial/scripts/initialize_db.py @@ -0,0 +1,44 @@ +import os +import sys + +from pyramid.paster import bootstrap, setup_logging +from sqlalchemy.exc import OperationalError + +from .. import models + + +def setup_models(dbsession): + model = models.MyModel(name='one', value=1) + dbsession.add(model) + + +def usage(argv): + cmd = os.path.basename(argv[0]) + print('usage: %s \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) + env = bootstrap(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/tutorials/wiki2/src/installation/tutorial/scripts/initializedb.py b/docs/tutorials/wiki2/src/installation/tutorial/scripts/initializedb.py deleted file mode 100644 index 7307ecc5c..000000000 --- a/docs/tutorials/wiki2/src/installation/tutorial/scripts/initializedb.py +++ /dev/null @@ -1,45 +0,0 @@ -import os -import sys -import transaction - -from pyramid.paster import ( - get_appsettings, - setup_logging, - ) - -from pyramid.scripts.common import parse_vars - -from ..models.meta import Base -from ..models import ( - get_engine, - get_session_factory, - get_tm_session, - ) -from ..models import MyModel - - -def usage(argv): - cmd = os.path.basename(argv[0]) - print('usage: %s [var=value]\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] - options = parse_vars(argv[2:]) - setup_logging(config_uri) - settings = get_appsettings(config_uri, options=options) - - engine = get_engine(settings) - Base.metadata.create_all(engine) - - session_factory = get_session_factory(engine) - - with transaction.manager: - dbsession = get_tm_session(session_factory, transaction.manager) - - model = MyModel(name='one', value=1) - dbsession.add(model) diff --git a/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2 b/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2 index 26d72c0a6..d8b0a4232 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2 +++ b/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2 @@ -5,4 +5,4 @@

Pyramid Alchemy project

Welcome to {{project}}, a Pyramid application generated by
Cookiecutter.

-{% endblock content %} +{% endblock content %} \ No newline at end of file diff --git a/docs/tutorials/wiki2/src/installation/tutorial/views/default.py b/docs/tutorials/wiki2/src/installation/tutorial/views/default.py index a404d4154..f8793ffb5 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/installation/tutorial/views/default.py @@ -20,9 +20,8 @@ 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_tutorial_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 -- cgit v1.2.3 From 8b43919a98177d4591736c3125b79ab0eeed290f Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 22 Jun 2018 18:09:59 -0700 Subject: Update source files for basiclayout step for Alembic support --- docs/tutorials/wiki2/src/basiclayout/README.txt | 14 ++++++- .../wiki2/src/basiclayout/development.ini | 6 +++ .../tutorials/wiki2/src/basiclayout/production.ini | 6 +++ docs/tutorials/wiki2/src/basiclayout/pytest.ini | 2 +- docs/tutorials/wiki2/src/basiclayout/setup.py | 3 +- .../basiclayout/tutorial/scripts/initializedb.py | 45 ---------------------- .../src/basiclayout/tutorial/views/default.py | 5 +-- .../tutorial/templates/mytemplate.jinja2 | 2 +- 8 files changed, 30 insertions(+), 53 deletions(-) delete mode 100644 docs/tutorials/wiki2/src/basiclayout/tutorial/scripts/initializedb.py (limited to 'docs/tutorials/wiki2/src') diff --git a/docs/tutorials/wiki2/src/basiclayout/README.txt b/docs/tutorials/wiki2/src/basiclayout/README.txt index 7b33da610..6d2df698e 100644 --- a/docs/tutorials/wiki2/src/basiclayout/README.txt +++ b/docs/tutorials/wiki2/src/basiclayout/README.txt @@ -20,9 +20,19 @@ Getting Started env/bin/pip install -e ".[testing]" -- Configure the database. +- Initialize the database using Alembic. - env/bin/initialize_tutorial_db development.ini + - 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. + + env/bin/initialize_tutorial_db development.ini - Run your project's tests. diff --git a/docs/tutorials/wiki2/src/basiclayout/development.ini b/docs/tutorials/wiki2/src/basiclayout/development.ini index 4a67896b2..ee050c0ea 100644 --- a/docs/tutorials/wiki2/src/basiclayout/development.ini +++ b/docs/tutorials/wiki2/src/basiclayout/development.ini @@ -26,6 +26,12 @@ retry.attempts = 3 # wsgi server configuration ### +[alembic] +# path to migration scripts +script_location = tutorial/alembic +file_template = %%(year)d%%(month).2d%%(day).2d_%%(rev)s +# file_template = %%(rev)s_%%(slug)s + [server:main] use = egg:waitress#main listen = localhost:6543 diff --git a/docs/tutorials/wiki2/src/basiclayout/production.ini b/docs/tutorials/wiki2/src/basiclayout/production.ini index a28e47a83..91d0f5ddb 100644 --- a/docs/tutorials/wiki2/src/basiclayout/production.ini +++ b/docs/tutorials/wiki2/src/basiclayout/production.ini @@ -20,6 +20,12 @@ retry.attempts = 3 # wsgi server configuration ### +[alembic] +# path to migration scripts +script_location = tutorial/alembic +file_template = %%(year)d%%(month).2d%%(day).2d_%%(rev)s +# file_template = %%(rev)s_%%(slug)s + [server:main] use = egg:waitress#main listen = *:6543 diff --git a/docs/tutorials/wiki2/src/basiclayout/pytest.ini b/docs/tutorials/wiki2/src/basiclayout/pytest.ini index 8b76bc410..a3489cdf8 100644 --- a/docs/tutorials/wiki2/src/basiclayout/pytest.ini +++ b/docs/tutorials/wiki2/src/basiclayout/pytest.ini @@ -1,3 +1,3 @@ [pytest] testpaths = tutorial -python_files = *.py +python_files = test*.py diff --git a/docs/tutorials/wiki2/src/basiclayout/setup.py b/docs/tutorials/wiki2/src/basiclayout/setup.py index 9fc5519a5..1638ef28e 100644 --- a/docs/tutorials/wiki2/src/basiclayout/setup.py +++ b/docs/tutorials/wiki2/src/basiclayout/setup.py @@ -9,6 +9,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: CHANGES = f.read() requires = [ + 'alembic', 'plaster_pastedeploy', 'pyramid >= 1.9a', 'pyramid_debugtoolbar', @@ -54,7 +55,7 @@ setup( 'main = tutorial:main', ], 'console_scripts': [ - 'initialize_tutorial_db = tutorial.scripts.initializedb:main', + 'initialize_tutorial_db = tutorial.scripts.initialize_db:main', ], }, ) diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/scripts/initializedb.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/scripts/initializedb.py deleted file mode 100644 index 7307ecc5c..000000000 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/scripts/initializedb.py +++ /dev/null @@ -1,45 +0,0 @@ -import os -import sys -import transaction - -from pyramid.paster import ( - get_appsettings, - setup_logging, - ) - -from pyramid.scripts.common import parse_vars - -from ..models.meta import Base -from ..models import ( - get_engine, - get_session_factory, - get_tm_session, - ) -from ..models import MyModel - - -def usage(argv): - cmd = os.path.basename(argv[0]) - print('usage: %s [var=value]\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] - options = parse_vars(argv[2:]) - setup_logging(config_uri) - settings = get_appsettings(config_uri, options=options) - - engine = get_engine(settings) - Base.metadata.create_all(engine) - - session_factory = get_session_factory(engine) - - with transaction.manager: - dbsession = get_tm_session(session_factory, transaction.manager) - - model = MyModel(name='one', value=1) - dbsession.add(model) diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py index a404d4154..f8793ffb5 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/views/default.py @@ -20,9 +20,8 @@ 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_tutorial_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 diff --git a/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2 b/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2 index d8b0a4232..26d72c0a6 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2 +++ b/docs/tutorials/wiki2/src/installation/tutorial/templates/mytemplate.jinja2 @@ -5,4 +5,4 @@

Pyramid Alchemy project

Welcome to {{project}}, a Pyramid application generated by
Cookiecutter.

-{% endblock content %} \ No newline at end of file +{% endblock content %} -- cgit v1.2.3 From 487df3c860346b02b6c69f8c0fed528fc5e7084a Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 25 Jun 2018 14:40:05 -0700 Subject: Synch up readmes with cookiecutter --- docs/tutorials/wiki2/src/basiclayout/README.txt | 6 +++--- docs/tutorials/wiki2/src/installation/README.txt | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) (limited to 'docs/tutorials/wiki2/src') diff --git a/docs/tutorials/wiki2/src/basiclayout/README.txt b/docs/tutorials/wiki2/src/basiclayout/README.txt index 6d2df698e..5d5133e34 100644 --- a/docs/tutorials/wiki2/src/basiclayout/README.txt +++ b/docs/tutorials/wiki2/src/basiclayout/README.txt @@ -20,7 +20,7 @@ Getting Started env/bin/pip install -e ".[testing]" -- Initialize the database using Alembic. +- Initialize and upgrade the database using Alembic. - Generate your first revision. @@ -30,9 +30,9 @@ Getting Started env/bin/alembic -c development.ini upgrade head - - Load default data. +- Load default data into the database using a script. - env/bin/initialize_tutorial_db development.ini + env/bin/initialize_tutorial_db development.ini - Run your project's tests. diff --git a/docs/tutorials/wiki2/src/installation/README.txt b/docs/tutorials/wiki2/src/installation/README.txt index 6d2df698e..5d5133e34 100644 --- a/docs/tutorials/wiki2/src/installation/README.txt +++ b/docs/tutorials/wiki2/src/installation/README.txt @@ -20,7 +20,7 @@ Getting Started env/bin/pip install -e ".[testing]" -- Initialize the database using Alembic. +- Initialize and upgrade the database using Alembic. - Generate your first revision. @@ -30,9 +30,9 @@ Getting Started env/bin/alembic -c development.ini upgrade head - - Load default data. +- Load default data into the database using a script. - env/bin/initialize_tutorial_db development.ini + env/bin/initialize_tutorial_db development.ini - Run your project's tests. -- cgit v1.2.3 From a0cdd7b3a9059cc3fd57f084940174014e6d2c1c Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Mon, 25 Jun 2018 14:40:28 -0700 Subject: add missing .gitignore --- docs/tutorials/wiki2/src/basiclayout/.gitignore | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 docs/tutorials/wiki2/src/basiclayout/.gitignore (limited to 'docs/tutorials/wiki2/src') diff --git a/docs/tutorials/wiki2/src/basiclayout/.gitignore b/docs/tutorials/wiki2/src/basiclayout/.gitignore new file mode 100644 index 000000000..1853d983c --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/.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 -- cgit v1.2.3 From 9ce49866130be6b697e7b5ea5e0f1bb35d3ba7bc Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 26 Jun 2018 00:06:09 -0700 Subject: Add omitted files to basiclayout step --- .../wiki2/src/basiclayout/tutorial/alembic/env.py | 58 ++++++++++++++++++++++ .../basiclayout/tutorial/alembic/script.py.mako | 24 +++++++++ .../tutorial/alembic/versions/README.txt | 1 + .../basiclayout/tutorial/scripts/initialize_db.py | 44 ++++++++++++++++ 4 files changed, 127 insertions(+) create mode 100644 docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/env.py create mode 100644 docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/script.py.mako create mode 100644 docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/versions/README.txt create mode 100644 docs/tutorials/wiki2/src/basiclayout/tutorial/scripts/initialize_db.py (limited to 'docs/tutorials/wiki2/src') diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/env.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/env.py new file mode 100644 index 000000000..730785899 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/env.py @@ -0,0 +1,58 @@ +"""Pyramid bootstrap environment. """ +from alembic import context +from pyramid.paster import get_appsettings, setup_logging + +from tutorial.models import get_engine +from tutorial.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 = get_engine(settings) + + 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/tutorials/wiki2/src/basiclayout/tutorial/alembic/script.py.mako b/docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/script.py.mako new file mode 100644 index 000000000..2c0156303 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/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/tutorials/wiki2/src/basiclayout/tutorial/alembic/versions/README.txt b/docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/versions/README.txt new file mode 100644 index 000000000..09ed32c8d --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/versions/README.txt @@ -0,0 +1 @@ +Placeholder for alembic versions \ No newline at end of file diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/scripts/initialize_db.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/scripts/initialize_db.py new file mode 100644 index 000000000..5b129e761 --- /dev/null +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/scripts/initialize_db.py @@ -0,0 +1,44 @@ +import os +import sys + +from pyramid.paster import bootstrap, setup_logging +from sqlalchemy.exc import OperationalError + +from .. import models + + +def setup_models(dbsession): + model = models.MyModel(name='one', value=1) + dbsession.add(model) + + +def usage(argv): + cmd = os.path.basename(argv[0]) + print('usage: %s \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) + env = bootstrap(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. + ''') -- cgit v1.2.3 From 66086301a8d85444bb608e4158c15f25b5ae2cdc Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 26 Jun 2018 00:08:18 -0700 Subject: Add alembic, correct name of init script in setup.py - Adjust linenos in defining models step - Update package version numbers to latest --- docs/tutorials/wiki2/src/models/setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'docs/tutorials/wiki2/src') diff --git a/docs/tutorials/wiki2/src/models/setup.py b/docs/tutorials/wiki2/src/models/setup.py index c688c6866..434487d15 100644 --- a/docs/tutorials/wiki2/src/models/setup.py +++ b/docs/tutorials/wiki2/src/models/setup.py @@ -9,6 +9,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: CHANGES = f.read() requires = [ + 'alembic', 'bcrypt', 'plaster_pastedeploy', 'pyramid >= 1.9a', @@ -55,7 +56,7 @@ setup( 'main = tutorial:main', ], 'console_scripts': [ - 'initialize_tutorial_db = tutorial.scripts.initializedb:main', + 'initialize_tutorial_db = tutorial.scripts.initialize_db:main', ], }, ) -- cgit v1.2.3 From beeee29617d64f67f8eec2991f6b413351393c9e Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 26 Jun 2018 00:30:17 -0700 Subject: rename script to align with cookiecutter default --- .../src/models/tutorial/scripts/initialize_db.py | 57 ++++++++++++++++++++++ .../src/models/tutorial/scripts/initializedb.py | 57 ---------------------- 2 files changed, 57 insertions(+), 57 deletions(-) create mode 100644 docs/tutorials/wiki2/src/models/tutorial/scripts/initialize_db.py delete mode 100644 docs/tutorials/wiki2/src/models/tutorial/scripts/initializedb.py (limited to 'docs/tutorials/wiki2/src') diff --git a/docs/tutorials/wiki2/src/models/tutorial/scripts/initialize_db.py b/docs/tutorials/wiki2/src/models/tutorial/scripts/initialize_db.py new file mode 100644 index 000000000..f3c0a6fef --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/scripts/initialize_db.py @@ -0,0 +1,57 @@ +import os +import sys +import transaction + +from pyramid.paster import ( + get_appsettings, + setup_logging, + ) + +from pyramid.scripts.common import parse_vars + +from ..models.meta import Base +from ..models import ( + get_engine, + get_session_factory, + get_tm_session, + ) +from ..models import Page, User + + +def usage(argv): + cmd = os.path.basename(argv[0]) + print('usage: %s [var=value]\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] + options = parse_vars(argv[2:]) + setup_logging(config_uri) + settings = get_appsettings(config_uri, options=options) + + engine = get_engine(settings) + Base.metadata.create_all(engine) + + session_factory = get_session_factory(engine) + + with transaction.manager: + dbsession = get_tm_session(session_factory, transaction.manager) + + editor = User(name='editor', role='editor') + editor.set_password('editor') + dbsession.add(editor) + + basic = User(name='basic', role='basic') + basic.set_password('basic') + dbsession.add(basic) + + page = Page( + name='FrontPage', + creator=editor, + data='This is the front page', + ) + dbsession.add(page) diff --git a/docs/tutorials/wiki2/src/models/tutorial/scripts/initializedb.py b/docs/tutorials/wiki2/src/models/tutorial/scripts/initializedb.py deleted file mode 100644 index f3c0a6fef..000000000 --- a/docs/tutorials/wiki2/src/models/tutorial/scripts/initializedb.py +++ /dev/null @@ -1,57 +0,0 @@ -import os -import sys -import transaction - -from pyramid.paster import ( - get_appsettings, - setup_logging, - ) - -from pyramid.scripts.common import parse_vars - -from ..models.meta import Base -from ..models import ( - get_engine, - get_session_factory, - get_tm_session, - ) -from ..models import Page, User - - -def usage(argv): - cmd = os.path.basename(argv[0]) - print('usage: %s [var=value]\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] - options = parse_vars(argv[2:]) - setup_logging(config_uri) - settings = get_appsettings(config_uri, options=options) - - engine = get_engine(settings) - Base.metadata.create_all(engine) - - session_factory = get_session_factory(engine) - - with transaction.manager: - dbsession = get_tm_session(session_factory, transaction.manager) - - editor = User(name='editor', role='editor') - editor.set_password('editor') - dbsession.add(editor) - - basic = User(name='basic', role='basic') - basic.set_password('basic') - dbsession.add(basic) - - page = Page( - name='FrontPage', - creator=editor, - data='This is the front page', - ) - dbsession.add(page) -- cgit v1.2.3 From 9f349cdeb347d792a510f3d223a76897b1269f13 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Tue, 26 Jun 2018 10:02:50 -0700 Subject: drop alpha status from pyramid requirement in setup.py - See https://github.com/Pylons/pyramid-cookiecutter-alchemy/issues/34 --- docs/tutorials/wiki2/src/basiclayout/setup.py | 2 +- docs/tutorials/wiki2/src/installation/setup.py | 2 +- docs/tutorials/wiki2/src/models/setup.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'docs/tutorials/wiki2/src') diff --git a/docs/tutorials/wiki2/src/basiclayout/setup.py b/docs/tutorials/wiki2/src/basiclayout/setup.py index 1638ef28e..e0cc964fe 100644 --- a/docs/tutorials/wiki2/src/basiclayout/setup.py +++ b/docs/tutorials/wiki2/src/basiclayout/setup.py @@ -11,7 +11,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'alembic', 'plaster_pastedeploy', - 'pyramid >= 1.9a', + 'pyramid >= 1.9', 'pyramid_debugtoolbar', 'pyramid_jinja2', 'pyramid_retry', diff --git a/docs/tutorials/wiki2/src/installation/setup.py b/docs/tutorials/wiki2/src/installation/setup.py index 1638ef28e..e0cc964fe 100644 --- a/docs/tutorials/wiki2/src/installation/setup.py +++ b/docs/tutorials/wiki2/src/installation/setup.py @@ -11,7 +11,7 @@ with open(os.path.join(here, 'CHANGES.txt')) as f: requires = [ 'alembic', 'plaster_pastedeploy', - 'pyramid >= 1.9a', + 'pyramid >= 1.9', 'pyramid_debugtoolbar', 'pyramid_jinja2', 'pyramid_retry', diff --git a/docs/tutorials/wiki2/src/models/setup.py b/docs/tutorials/wiki2/src/models/setup.py index 434487d15..2576cc848 100644 --- a/docs/tutorials/wiki2/src/models/setup.py +++ b/docs/tutorials/wiki2/src/models/setup.py @@ -12,7 +12,7 @@ requires = [ 'alembic', 'bcrypt', 'plaster_pastedeploy', - 'pyramid >= 1.9a', + 'pyramid >= 1.9', 'pyramid_debugtoolbar', 'pyramid_jinja2', 'pyramid_retry', -- cgit v1.2.3 From 5b3f50e56b2e4a64be29a54ca8d27a9836dec6a9 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 27 Jun 2018 16:26:55 -0700 Subject: switch to engine_from_config to be consistent with run_migrations_offline See https://github.com/Pylons/pyramid-cookiecutter-alchemy/commit/f1ab68543d3e44fc1a5df0aa0355f08578f38b7a --- docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/env.py | 4 ++-- docs/tutorials/wiki2/src/installation/tutorial/alembic/env.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/tutorials/wiki2/src') diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/env.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/env.py index 730785899..ba116d0f3 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/env.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/alembic/env.py @@ -1,8 +1,8 @@ """Pyramid bootstrap environment. """ from alembic import context from pyramid.paster import get_appsettings, setup_logging +from sqlalchemy import engine_from_config -from tutorial.models import get_engine from tutorial.models.meta import Base config = context.config @@ -37,7 +37,7 @@ def run_migrations_online(): and associate a connection with the context. """ - engine = get_engine(settings) + engine = engine_from_config(settings, prefix='sqlalchemy.') connection = engine.connect() context.configure( diff --git a/docs/tutorials/wiki2/src/installation/tutorial/alembic/env.py b/docs/tutorials/wiki2/src/installation/tutorial/alembic/env.py index 730785899..ba116d0f3 100644 --- a/docs/tutorials/wiki2/src/installation/tutorial/alembic/env.py +++ b/docs/tutorials/wiki2/src/installation/tutorial/alembic/env.py @@ -1,8 +1,8 @@ """Pyramid bootstrap environment. """ from alembic import context from pyramid.paster import get_appsettings, setup_logging +from sqlalchemy import engine_from_config -from tutorial.models import get_engine from tutorial.models.meta import Base config = context.config @@ -37,7 +37,7 @@ def run_migrations_online(): and associate a connection with the context. """ - engine = get_engine(settings) + engine = engine_from_config(settings, prefix='sqlalchemy.') connection = engine.connect() context.configure( -- cgit v1.2.3 From 89e464b28c0aa87f452474ec0c9feacfd0ec47f3 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 27 Jun 2018 16:27:22 -0700 Subject: Add alembic directory to source in models step --- .../wiki2/src/models/tutorial/alembic/env.py | 58 ++++++++++++++++++++++ .../src/models/tutorial/alembic/script.py.mako | 24 +++++++++ .../models/tutorial/alembic/versions/README.txt | 1 + 3 files changed, 83 insertions(+) create mode 100644 docs/tutorials/wiki2/src/models/tutorial/alembic/env.py create mode 100644 docs/tutorials/wiki2/src/models/tutorial/alembic/script.py.mako create mode 100644 docs/tutorials/wiki2/src/models/tutorial/alembic/versions/README.txt (limited to 'docs/tutorials/wiki2/src') diff --git a/docs/tutorials/wiki2/src/models/tutorial/alembic/env.py b/docs/tutorials/wiki2/src/models/tutorial/alembic/env.py new file mode 100644 index 000000000..ba116d0f3 --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/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 tutorial.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/tutorials/wiki2/src/models/tutorial/alembic/script.py.mako b/docs/tutorials/wiki2/src/models/tutorial/alembic/script.py.mako new file mode 100644 index 000000000..2c0156303 --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/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/tutorials/wiki2/src/models/tutorial/alembic/versions/README.txt b/docs/tutorials/wiki2/src/models/tutorial/alembic/versions/README.txt new file mode 100644 index 000000000..09ed32c8d --- /dev/null +++ b/docs/tutorials/wiki2/src/models/tutorial/alembic/versions/README.txt @@ -0,0 +1 @@ +Placeholder for alembic versions \ No newline at end of file -- cgit v1.2.3 From 0fa7506987e2a8d1fa68ab307ef325de5fb137ec Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 28 Jun 2018 01:46:42 -0700 Subject: First stab at updated db script --- .../src/models/tutorial/scripts/initialize_db.py | 77 +++++++++++----------- 1 file changed, 38 insertions(+), 39 deletions(-) (limited to 'docs/tutorials/wiki2/src') diff --git a/docs/tutorials/wiki2/src/models/tutorial/scripts/initialize_db.py b/docs/tutorials/wiki2/src/models/tutorial/scripts/initialize_db.py index f3c0a6fef..af4c625ae 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/scripts/initialize_db.py +++ b/docs/tutorials/wiki2/src/models/tutorial/scripts/initialize_db.py @@ -1,57 +1,56 @@ import os import sys -import transaction -from pyramid.paster import ( - get_appsettings, - setup_logging, - ) +from pyramid.paster import bootstrap, setup_logging +from sqlalchemy.exc import OperationalError + +from ..models import Page, User -from pyramid.scripts.common import parse_vars -from ..models.meta import Base -from ..models import ( - get_engine, - get_session_factory, - get_tm_session, +def setup_models(dbsession): + editor = User(name='editor', role='editor') + editor.set_password('editor') + dbsession.add(editor) + + basic = User(name='basic', role='basic') + basic.set_password('basic') + dbsession.add(basic) + + page = Page( + name='FrontPage', + creator=editor, + data='This is the front page', ) -from ..models import Page, User + dbsession.add(page) def usage(argv): cmd = os.path.basename(argv[0]) - print('usage: %s [var=value]\n' + print('usage: %s \n' '(example: "%s development.ini")' % (cmd, cmd)) sys.exit(1) def main(argv=sys.argv): - if len(argv) < 2: + if len(argv) != 2: usage(argv) config_uri = argv[1] - options = parse_vars(argv[2:]) setup_logging(config_uri) - settings = get_appsettings(config_uri, options=options) - - engine = get_engine(settings) - Base.metadata.create_all(engine) - - session_factory = get_session_factory(engine) - - with transaction.manager: - dbsession = get_tm_session(session_factory, transaction.manager) - - editor = User(name='editor', role='editor') - editor.set_password('editor') - dbsession.add(editor) - - basic = User(name='basic', role='basic') - basic.set_password('basic') - dbsession.add(basic) - - page = Page( - name='FrontPage', - creator=editor, - data='This is the front page', - ) - dbsession.add(page) + env = bootstrap(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. + ''') -- cgit v1.2.3 From 80ab8e738e7c997d8931df83c5714e5959e7b4ba Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Thu, 28 Jun 2018 16:23:25 -0700 Subject: Change import to module scope --- docs/tutorials/wiki2/src/models/tutorial/scripts/initialize_db.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'docs/tutorials/wiki2/src') diff --git a/docs/tutorials/wiki2/src/models/tutorial/scripts/initialize_db.py b/docs/tutorials/wiki2/src/models/tutorial/scripts/initialize_db.py index af4c625ae..231d5d44b 100644 --- a/docs/tutorials/wiki2/src/models/tutorial/scripts/initialize_db.py +++ b/docs/tutorials/wiki2/src/models/tutorial/scripts/initialize_db.py @@ -4,19 +4,19 @@ import sys from pyramid.paster import bootstrap, setup_logging from sqlalchemy.exc import OperationalError -from ..models import Page, User +from .. import models def setup_models(dbsession): - editor = User(name='editor', role='editor') + editor = models.User(name='editor', role='editor') editor.set_password('editor') dbsession.add(editor) - basic = User(name='basic', role='basic') + basic = models.User(name='basic', role='basic') basic.set_password('basic') dbsession.add(basic) - page = Page( + page = models.Page( name='FrontPage', creator=editor, data='This is the front page', -- cgit v1.2.3 From c71eeae50ed148407c530de783f808cece8537e1 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Fri, 29 Jun 2018 00:25:15 -0700 Subject: Resynch src files to cookiecutter --- .../wiki2/src/basiclayout/tutorial/scripts/initialize_db.py | 2 +- .../wiki2/src/basiclayout/tutorial/templates/layout.jinja2 | 2 +- .../src/basiclayout/tutorial/templates/mytemplate.jinja2 | 2 +- .../wiki2/src/basiclayout/tutorial/views/default.py | 6 +++--- .../wiki2/src/installation/tutorial/scripts/initialize_db.py | 2 +- .../wiki2/src/installation/tutorial/templates/layout.jinja2 | 2 +- docs/tutorials/wiki2/src/models/README.txt | 12 +++++++++++- docs/tutorials/wiki2/src/models/development.ini | 6 ++++++ docs/tutorials/wiki2/src/models/production.ini | 6 ++++++ docs/tutorials/wiki2/src/models/pytest.ini | 2 +- .../wiki2/src/models/tutorial/templates/layout.jinja2 | 2 +- docs/tutorials/wiki2/src/models/tutorial/views/default.py | 11 +++++------ 12 files changed, 38 insertions(+), 17 deletions(-) (limited to 'docs/tutorials/wiki2/src') diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/scripts/initialize_db.py b/docs/tutorials/wiki2/src/basiclayout/tutorial/scripts/initialize_db.py index 5b129e761..b882f9bf7 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/scripts/initialize_db.py +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/scripts/initialize_db.py @@ -8,7 +8,7 @@ from .. import models def setup_models(dbsession): - model = models.MyModel(name='one', value=1) + model = models.mymodel.MyModel(name='one', value=1) dbsession.add(model) diff --git a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2 b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2 index 6ce99d08e..5d4313fe2 100644 --- a/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2 +++ b/docs/tutorials/wiki2/src/basiclayout/tutorial/templates/layout.jinja2 @@ -16,7 +16,7 @@ - + - + - + - + - + - + - +