From a8624e266206020ff93d8b972ee5aa34434e9354 Mon Sep 17 00:00:00 2001 From: Nils Philippsen Date: Sat, 14 Dec 2019 21:25:48 +0100 Subject: [PATCH 1/3] allow calling init_model() more than once Different levels of tests (e.g. app/functional, db model) can cause init_model() to be called a couple of times. Dispose of the current session (if any) so subsequent tests can start with a clean slate. --- .../gearbox/quickstart/template/+package+/model/__init__.py_tmpl | 1 + 1 file changed, 1 insertion(+) diff --git a/devtools/gearbox/quickstart/template/+package+/model/__init__.py_tmpl b/devtools/gearbox/quickstart/template/+package+/model/__init__.py_tmpl index 4831ca0..1c11df8 100644 --- a/devtools/gearbox/quickstart/template/+package+/model/__init__.py_tmpl +++ b/devtools/gearbox/quickstart/template/+package+/model/__init__.py_tmpl @@ -49,6 +49,7 @@ def init_model(engine): """Call me before using any of the tables or classes in the model.""" {{if sqlalchemy}} + DBSession.remove() DBSession.configure(bind=engine) # If you are using reflection to introspect your database and create From 125239d4b73a5b3332513f8cb8cf0eb6718319b6 Mon Sep 17 00:00:00 2001 From: Nils Philippsen Date: Sat, 14 Dec 2019 22:11:39 +0100 Subject: [PATCH 2/3] tests: use transaction API to roll back changes Mixed use of transaction and SQLAlchemy session APIs for handling transactions in tests can cause consecutive tests that in some way access the database to fail. The websetup package uses the transaction API, so use the same in the model test harness. --- .../template/+package+/tests/models/__init__.py_tmpl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/devtools/gearbox/quickstart/template/+package+/tests/models/__init__.py_tmpl b/devtools/gearbox/quickstart/template/+package+/tests/models/__init__.py_tmpl index 62bba39..d784d03 100644 --- a/devtools/gearbox/quickstart/template/+package+/tests/models/__init__.py_tmpl +++ b/devtools/gearbox/quickstart/template/+package+/tests/models/__init__.py_tmpl @@ -4,6 +4,8 @@ from nose.tools import eq_ {{if sqlalchemy}} +import transaction + from {{package}}.model import DBSession {{elif ming}} from tg import config @@ -64,7 +66,7 @@ class ModelTest(object): # On MongoDB drop database datastore.conn.drop_database(datastore.db) {{elif sqlalchemy}} - DBSession.rollback() + transaction.abort() {{endif}} raise @@ -79,7 +81,7 @@ class ModelTest(object): # On MongoDB drop database datastore.conn.drop_database(datastore.db) {{elif sqlalchemy}} - DBSession.rollback() + transaction.abort() {{endif}} def do_get_dependencies(self): From 1774d1812c1642614e55a67b33f613461066a629 Mon Sep 17 00:00:00 2001 From: Nils Philippsen Date: Sun, 15 Dec 2019 02:51:13 +0100 Subject: [PATCH 3/3] websetup: explicitly begin transactions This is to deal with potentially aborted transactions in tests. --- .../quickstart/template/+package+/websetup/bootstrap.py_tmpl | 1 + .../quickstart/template/+package+/websetup/schema.py_tmpl | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/devtools/gearbox/quickstart/template/+package+/websetup/bootstrap.py_tmpl b/devtools/gearbox/quickstart/template/+package+/websetup/bootstrap.py_tmpl index 37d86ec..1cdeabb 100644 --- a/devtools/gearbox/quickstart/template/+package+/websetup/bootstrap.py_tmpl +++ b/devtools/gearbox/quickstart/template/+package+/websetup/bootstrap.py_tmpl @@ -15,6 +15,7 @@ def bootstrap(command, conf, vars): {{if auth == "sqlalchemy"}} from sqlalchemy.exc import IntegrityError try: + transaction.begin() u = model.User() u.user_name = 'manager' u.display_name = 'Example manager' diff --git a/devtools/gearbox/quickstart/template/+package+/websetup/schema.py_tmpl b/devtools/gearbox/quickstart/template/+package+/websetup/schema.py_tmpl index d7e5e19..70998e1 100644 --- a/devtools/gearbox/quickstart/template/+package+/websetup/schema.py_tmpl +++ b/devtools/gearbox/quickstart/template/+package+/websetup/schema.py_tmpl @@ -17,6 +17,7 @@ def setup_schema(command, conf, vars): from {{package}} import model # + transaction.begin() # print("Creating tables") model.metadata.create_all(bind=config['tg.app_globals'].sa_engine) @@ -32,4 +33,4 @@ def setup_schema(command, conf, vars): alembic_cfg.set_main_option("sqlalchemy.url", config['sqlalchemy.url']) import alembic.command alembic.command.stamp(alembic_cfg, "head") - {{endif}} \ No newline at end of file + {{endif}}