__init__.py 2.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. # -*- coding: utf-8 -*-
  2. from sqlalchemy import engine_from_config
  3. from sqlalchemy.event import listen
  4. from sqlalchemy.orm import sessionmaker
  5. from sqlalchemy.orm import configure_mappers
  6. import zope.sqlalchemy
  7. from .meta import DeclarativeBase
  8. from .revision_protection import prevent_content_revision_delete
  9. # import or define all models here to ensure they are attached to the
  10. # Base.metadata prior to any initialization routines
  11. from tracim.models.mymodel import MyModel # flake8: noqa
  12. from tracim.models.auth import User, Group, Permission
  13. from tracim.models.data import Content, ContentRevisionRO
  14. # run configure_mappers after defining all of the models to ensure
  15. # all relationships can be setup
  16. configure_mappers()
  17. def get_engine(settings, prefix='sqlalchemy.'):
  18. return engine_from_config(settings, prefix)
  19. def get_session_factory(engine):
  20. factory = sessionmaker(expire_on_commit=False)
  21. factory.configure(bind=engine)
  22. return factory
  23. def get_tm_session(session_factory, transaction_manager):
  24. """
  25. Get a ``sqlalchemy.orm.Session`` instance backed by a transaction.
  26. This function will hook the _session to the transaction manager which
  27. will take care of committing any changes.
  28. - When using pyramid_tm it will automatically be committed or aborted
  29. depending on whether an exception is raised.
  30. - When using scripts you should wrap the _session in a manager yourself.
  31. For example::
  32. import transaction
  33. engine = get_engine(settings)
  34. session_factory = get_session_factory(engine)
  35. with transaction.manager:
  36. dbsession = get_tm_session(session_factory, transaction.manager)
  37. """
  38. dbsession = session_factory()
  39. zope.sqlalchemy.register(
  40. dbsession, transaction_manager=transaction_manager)
  41. listen(dbsession, 'before_flush', prevent_content_revision_delete)
  42. return dbsession
  43. def includeme(config):
  44. """
  45. Initialize the model for a Pyramid app.
  46. Activate this setup using ``config.include('tracim.models')``.
  47. """
  48. settings = config.get_settings()
  49. settings['tm.manager_hook'] = 'pyramid_tm.explicit_manager'
  50. # use pyramid_tm to hook the transaction lifecycle to the request
  51. config.include('pyramid_tm')
  52. # use pyramid_retry to retry a request when transient exceptions occur
  53. config.include('pyramid_retry')
  54. session_factory = get_session_factory(get_engine(settings))
  55. config.registry['dbsession_factory'] = session_factory
  56. # make request.dbsession available for use in Pyramid
  57. config.add_request_method(
  58. # r.tm is the transaction manager used by pyramid_tm
  59. lambda r: get_tm_session(session_factory, r.tm),
  60. 'dbsession',
  61. reify=True
  62. )