summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Merickel <michael@merickel.org>2016-02-03 23:46:40 -0600
committerMichael Merickel <michael@merickel.org>2016-02-03 23:47:24 -0600
commita6d08e1ad8c8bbcc7e14eabf06e26507e636d538 (patch)
treef92c7fd83e78197382605ba8f7f67fcfbbdb65dd
parent3eb1c354d320536ee470b79dcb930d20da93d97d (diff)
downloadpyramid-a6d08e1ad8c8bbcc7e14eabf06e26507e636d538.tar.gz
pyramid-a6d08e1ad8c8bbcc7e14eabf06e26507e636d538.tar.bz2
pyramid-a6d08e1ad8c8bbcc7e14eabf06e26507e636d538.zip
improve the models api/usage and add a lot of comments
-rw-r--r--pyramid/scaffolds/alchemy/+package+/__init__.py2
-rw-r--r--pyramid/scaffolds/alchemy/+package+/models/__init__.py71
-rw-r--r--pyramid/scaffolds/alchemy/+package+/models/meta.py33
-rw-r--r--pyramid/scaffolds/alchemy/+package+/models/mymodel.py3
-rw-r--r--pyramid/scaffolds/alchemy/+package+/scripts/initializedb.py9
-rw-r--r--pyramid/scaffolds/alchemy/+package+/tests.py_tmpl8
6 files changed, 80 insertions, 46 deletions
diff --git a/pyramid/scaffolds/alchemy/+package+/__init__.py b/pyramid/scaffolds/alchemy/+package+/__init__.py
index 7994bbfa8..17763812a 100644
--- a/pyramid/scaffolds/alchemy/+package+/__init__.py
+++ b/pyramid/scaffolds/alchemy/+package+/__init__.py
@@ -6,7 +6,7 @@ def main(global_config, **settings):
"""
config = Configurator(settings=settings)
config.include('pyramid_jinja2')
- config.include('.models.meta')
+ config.include('.models')
config.add_static_view('static', 'static', cache_max_age=3600)
config.add_route('home', '/')
config.scan()
diff --git a/pyramid/scaffolds/alchemy/+package+/models/__init__.py b/pyramid/scaffolds/alchemy/+package+/models/__init__.py
index 6ffc10a78..e55689f2c 100644
--- a/pyramid/scaffolds/alchemy/+package+/models/__init__.py
+++ b/pyramid/scaffolds/alchemy/+package+/models/__init__.py
@@ -1,7 +1,72 @@
+from sqlalchemy import engine_from_config
+from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm import configure_mappers
-# import all models classes here for sqlalchemy mappers
-# to pick up
+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 to ensure we avoid any race conditions
+# 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_sessionmaker(engine):
+ dbmaker = sessionmaker()
+ dbmaker.configure(bind=engine)
+ return dbmaker
+
+
+def get_tm_session(dbmaker, 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)
+ dbmaker = get_sessionmaker(engine)
+ with transaction.manager:
+ dbsession = get_tm_session(dbmaker, transaction.manager)
+
+ """
+ dbsession = dbmaker()
+ 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('{{package}}.models')``.
+
+ """
+ settings = config.get_settings()
+
+ # use pyramid_tm to hook the transaction lifecycle to the request
+ config.include('pyramid_tm')
+
+ dbmaker = get_sessionmaker(get_engine(settings))
+
+ # 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(dbmaker, r.tm),
+ 'dbsession',
+ reify=True
+ )
diff --git a/pyramid/scaffolds/alchemy/+package+/models/meta.py b/pyramid/scaffolds/alchemy/+package+/models/meta.py
index 80ececd8c..fc3e8f1dd 100644
--- a/pyramid/scaffolds/alchemy/+package+/models/meta.py
+++ b/pyramid/scaffolds/alchemy/+package+/models/meta.py
@@ -1,8 +1,5 @@
-from sqlalchemy import engine_from_config
from sqlalchemy.ext.declarative import declarative_base
-from sqlalchemy.orm import sessionmaker
from sqlalchemy.schema import MetaData
-import zope.sqlalchemy
# Recommended naming convention used by Alembic, as various different database
# providers will autogenerate vastly different names making migrations more
@@ -17,33 +14,3 @@ NAMING_CONVENTION = {
metadata = MetaData(naming_convention=NAMING_CONVENTION)
Base = declarative_base(metadata=metadata)
-
-
-def includeme(config):
- settings = config.get_settings()
- dbmaker = get_dbmaker(get_engine(settings))
-
- config.add_request_method(
- lambda r: get_session(r.tm, dbmaker),
- 'dbsession',
- reify=True
- )
-
- config.include('pyramid_tm')
-
-
-def get_session(transaction_manager, dbmaker):
- dbsession = dbmaker()
- zope.sqlalchemy.register(dbsession,
- transaction_manager=transaction_manager)
- return dbsession
-
-
-def get_engine(settings, prefix='sqlalchemy.'):
- return engine_from_config(settings, prefix)
-
-
-def get_dbmaker(engine):
- dbmaker = sessionmaker()
- dbmaker.configure(bind=engine)
- return dbmaker
diff --git a/pyramid/scaffolds/alchemy/+package+/models/mymodel.py b/pyramid/scaffolds/alchemy/+package+/models/mymodel.py
index 5a2b5890c..d65a01a42 100644
--- a/pyramid/scaffolds/alchemy/+package+/models/mymodel.py
+++ b/pyramid/scaffolds/alchemy/+package+/models/mymodel.py
@@ -1,4 +1,3 @@
-from .meta import Base
from sqlalchemy import (
Column,
Index,
@@ -6,6 +5,8 @@ from sqlalchemy import (
Text,
)
+from .meta import Base
+
class MyModel(Base):
__tablename__ = 'models'
diff --git a/pyramid/scaffolds/alchemy/+package+/scripts/initializedb.py b/pyramid/scaffolds/alchemy/+package+/scripts/initializedb.py
index 0b2a42c59..13d4e543e 100644
--- a/pyramid/scaffolds/alchemy/+package+/scripts/initializedb.py
+++ b/pyramid/scaffolds/alchemy/+package+/scripts/initializedb.py
@@ -11,9 +11,9 @@ from pyramid.scripts.common import parse_vars
from ..models import (
Base,
- get_session,
get_engine,
- get_dbmaker,
+ get_sessionmaker,
+ get_tm_session,
)
from ..models import MyModel
@@ -36,9 +36,10 @@ def main(argv=sys.argv):
engine = get_engine(settings)
Base.metadata.create_all(engine)
- dbmaker = get_dbmaker(engine)
- dbsession = get_session(transaction.manager, dbmaker)
+ dbmaker = get_sessionmaker(engine)
with transaction.manager:
+ dbsession = get_tm_session(dbmaker, transaction.manager)
+
model = MyModel(name='one', value=1)
dbsession.add(model)
diff --git a/pyramid/scaffolds/alchemy/+package+/tests.py_tmpl b/pyramid/scaffolds/alchemy/+package+/tests.py_tmpl
index 01f2cb4cc..4eecaf33c 100644
--- a/pyramid/scaffolds/alchemy/+package+/tests.py_tmpl
+++ b/pyramid/scaffolds/alchemy/+package+/tests.py_tmpl
@@ -17,15 +17,15 @@ class BaseTest(unittest.TestCase):
settings = self.config.get_settings()
from .models import (
- get_session,
get_engine,
- get_dbmaker,
+ get_sessionmaker,
+ get_tm_session,
)
self.engine = get_engine(settings)
- dbmaker = get_dbmaker(self.engine)
+ dbmaker = get_sessionmaker(self.engine)
- self.session = get_session(transaction.manager, dbmaker)
+ self.session = get_tm_session(dbmaker, transaction.manager)
def init_database(self):
from .models import Base