more.pony


Namemore.pony JSON
Version 0.4 PyPI version JSON
download
home_pagehttps://github.com/morepath/more.pony
SummaryPony ORM integration in Morepath
upload_time2024-03-03 02:17:42
maintainer
docs_urlNone
authorHenri Hulski
requires_python
licenseBSD
keywords morepath pony orm ponyorm
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            .. image:: https://github.com/morepath/more.pony/workflows/CI/badge.svg?branch=master
   :target: https://github.com/morepath/more.pony/actions?workflow=CI
   :alt: CI Status

.. image:: https://img.shields.io/pypi/v/more.pony.svg
  :target: https://pypi.org/project/more.pony/

.. image:: https://img.shields.io/pypi/pyversions/more.pony.svg
  :target: https://pypi.org/project/more.pony/


more.pony: Pony ORM integration in Morepath
===========================================

This package provides Morepath integration for the Pony_
Object-Relational Mapper library.

This package binds the database session to the request so
you can interact with the database in your App directly
without using ``db_session``.


Quick start
-----------

Install ``more.pony``:

.. code-block:: console

  $ pip install -U more.pony

Extend your App class from PonyApp:

.. code-block:: python

    from more.pony import PonyApp

    class App(PonyApp):
        pass


Create your model:

.. code-block:: python

  from pony.orm import Database, PrimaryKey, Optional

  db = Database()


  class Document(db.Entity):
      _table_ = 'document'

      id = PrimaryKey(int, auto=True)
      title = Optional(str)
      content = Optional(str)

      def update(self, payload={}):
          self.set(**payload)

      def remove(self):
          self.delete()


Setup the database in your start script:

.. code-block:: python

  import morepath

  from .app import App
  from .model import db


  def run():
      db.bind(provider='sqlite', filename='app.db', create_db=True)
      db.generate_mapping(create_tables=True)

      morepath.autoscan()
      morepath.run(App())


Now you can use the model in your path:

.. code-block:: python

  from .app import App
  from .model import Document


  @App.path(model=Document, path='documents/{id}')
  def get_document(request, id=0):
      return Document[id]

And in your view:

.. code-block:: python

  from .app import App
  from .model import Document


  @App.json(model=Document)
  def document_default(self, request):
      return {
          'id': self.id,
          'title': self.title,
          'content': self.content,
          'link': request.link(self)
      }


  @App.json(model=Document, request_method='PUT')
  def document_update(self, request):
      self.update(request.json)


  @App.json(model=Document, request_method='DELETE')
  def document_remove(self, request):
      self.remove()


Settings
--------

You can set the arguments which are passed to ``db_session``
in the ``pony`` section of your settings.

The default settings are:

.. code-block:: python

  @App.setting_section(section='pony')
  def get_pony_settings():
      return {
          'allowed_exceptions': [],
          'immediate': False,
          'retry': 0,
          'retry_exceptions': [TransactionError],
          'serializable': False,
          'strict': False
      }

More information about the arguments you find in the `Pony API documentation`_.

You can also use the ``database`` settings section for your database setup,
which allows you to use different setups for production, development and
testing environments.

Just create create an App for each environment and load specific
settings files:

.. code-block:: python

  class App(PonyApp):
      pass

  with open('settings/default.yml') as defaults:
    defaults_dict = yaml.load(defaults)

  App.init_settings(defaults_dict)


  class ProductionApp(App):
      pass


  with open('settings/production.yml') as settings:
      settings_dict = yaml.load(settings)

  ProductionApp.init_settings(settings_dict)


  class TestApp(App):
      pass


  with open('settings/test.yml') as settings:
      settings_dict = yaml.load(settings)

  TestApp.init_settings(settings_dict)

The database configuration in the YAML settings
files, depending on the database you use, could
look something like:

.. code-block:: yaml

  database:
    provider: sqlite
    filename: app.db
    create_db: true

In your start script you setup the database and load
the App according to the ``RUN_ENV`` environment variable:

.. code-block:: python

  import os
  import morepath

  from .app import App, ProductionApp, TestApp
  from .model import db


  def setup_db(app):
      db_params = app.settings.database.__dict__.copy()
      db.bind(**db_params)
      db.generate_mapping(create_tables=True)

  def run():
    morepath.autoscan()

    if os.getenv('RUN_ENV') == 'production':
        ProductionApp.commit()
        app = ProductionApp()
    elif os.getenv('RUN_ENV') == 'test':
        TestApp.commit()
        app = TestApp()
    else:
        App.commit()
        app = App()

    setup_db(app)
    morepath.run(app)

Detail about the database configuration you find
in the `PonyOrm documentation`_.


Side effects
------------

If you want to trigger side effects (like sending an email or
writing to filesystem) on database commits you can emit a signal
in the ``@request.after`` of the view which triggers the side effects.

Like this the side effects will be triggered just before the
database session gets committed and only if it wasn't rolled back.

This example uses `more.emit`_:

.. code-block:: python

  @App.json(model=Document, request_method='PUT')
  def document_update(self, request):
      self.update(request.json)

      @request.after
      def after(response):
          request.app.signal.emit('document_updated', self, request)

Altenatively you can use in your model the PonyORM
`after_insert()`_, `after_update()`_ or `after_delete()`_
entity-hooks.
This makes sure that the side effect is triggered
**after** the database session has committed.

The drawback is that you don't have easy access to the
request or app in the model.


.. _Pony: https://ponyorm.com
.. _Pony API documentation:
    https://docs.ponyorm.com/api_reference.html#transactions-db-session
.. _PonyOrm documentation: https://docs.ponyorm.com/api_reference.html#database
.. _more.emit: https://github.com/morepath/more.emit
.. _after_insert(): https://docs.ponyorm.com/api_reference.html#after_insert
.. _after_update(): https://docs.ponyorm.com/api_reference.html#after_update
.. _after_delete(): https://docs.ponyorm.com/api_reference.html#after_delete


CHANGES
=======

0.4 (2024-03-03)
----------------

- **Removed**: Drop support for Python 3.4, 3.5, 3.6 and 3.7.

- Add support for Python 3.9, 3.10 and 3.11.

- Fix Flake8.

- Use GitHub Actions for CI.

- Make Python 3.11 the default testing environment.

- Upgrade PonyORM to 0.7.17.

- Show full diffs in the test output.

- Add Editors config and venv to .gitignore.

- Remove report to coveralls.

- Update pre-commit revs.


0.3 (2020-04-26)
----------------

- **Removed**: Removed support for Python 2.
  
  You have to upgrade to Python 3 if you want to use this version.

- Added support for Python 3.6, 3.7 and 3.8 and PyPy 3.6.

- Make Python 3.7 the default testing environment.

- Upgrade PonyORM to 0.7.13.

- Add integration for the Black code formatter.




0.2 (2017-07-20)
----------------

- Upgrade PonyORM to 0.7.2.
- Use a dictonary for passing parameters to db.bind in examples and tests.


0.1 (2017-04-22)
----------------

- Initial public release.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/morepath/more.pony",
    "name": "more.pony",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "morepath Pony ORM PonyORM",
    "author": "Henri Hulski",
    "author_email": "henri.hulski@gazeta.pl",
    "download_url": "https://files.pythonhosted.org/packages/fa/73/9b16249dc197407a4bf4e55fb0f757fd2381cd95a5042b95cd882e40ff2d/more.pony-0.4.tar.gz",
    "platform": null,
    "description": ".. image:: https://github.com/morepath/more.pony/workflows/CI/badge.svg?branch=master\n   :target: https://github.com/morepath/more.pony/actions?workflow=CI\n   :alt: CI Status\n\n.. image:: https://img.shields.io/pypi/v/more.pony.svg\n  :target: https://pypi.org/project/more.pony/\n\n.. image:: https://img.shields.io/pypi/pyversions/more.pony.svg\n  :target: https://pypi.org/project/more.pony/\n\n\nmore.pony: Pony ORM integration in Morepath\n===========================================\n\nThis package provides Morepath integration for the Pony_\nObject-Relational Mapper library.\n\nThis package binds the database session to the request so\nyou can interact with the database in your App directly\nwithout using ``db_session``.\n\n\nQuick start\n-----------\n\nInstall ``more.pony``:\n\n.. code-block:: console\n\n  $ pip install -U more.pony\n\nExtend your App class from PonyApp:\n\n.. code-block:: python\n\n    from more.pony import PonyApp\n\n    class App(PonyApp):\n        pass\n\n\nCreate your model:\n\n.. code-block:: python\n\n  from pony.orm import Database, PrimaryKey, Optional\n\n  db = Database()\n\n\n  class Document(db.Entity):\n      _table_ = 'document'\n\n      id = PrimaryKey(int, auto=True)\n      title = Optional(str)\n      content = Optional(str)\n\n      def update(self, payload={}):\n          self.set(**payload)\n\n      def remove(self):\n          self.delete()\n\n\nSetup the database in your start script:\n\n.. code-block:: python\n\n  import morepath\n\n  from .app import App\n  from .model import db\n\n\n  def run():\n      db.bind(provider='sqlite', filename='app.db', create_db=True)\n      db.generate_mapping(create_tables=True)\n\n      morepath.autoscan()\n      morepath.run(App())\n\n\nNow you can use the model in your path:\n\n.. code-block:: python\n\n  from .app import App\n  from .model import Document\n\n\n  @App.path(model=Document, path='documents/{id}')\n  def get_document(request, id=0):\n      return Document[id]\n\nAnd in your view:\n\n.. code-block:: python\n\n  from .app import App\n  from .model import Document\n\n\n  @App.json(model=Document)\n  def document_default(self, request):\n      return {\n          'id': self.id,\n          'title': self.title,\n          'content': self.content,\n          'link': request.link(self)\n      }\n\n\n  @App.json(model=Document, request_method='PUT')\n  def document_update(self, request):\n      self.update(request.json)\n\n\n  @App.json(model=Document, request_method='DELETE')\n  def document_remove(self, request):\n      self.remove()\n\n\nSettings\n--------\n\nYou can set the arguments which are passed to ``db_session``\nin the ``pony`` section of your settings.\n\nThe default settings are:\n\n.. code-block:: python\n\n  @App.setting_section(section='pony')\n  def get_pony_settings():\n      return {\n          'allowed_exceptions': [],\n          'immediate': False,\n          'retry': 0,\n          'retry_exceptions': [TransactionError],\n          'serializable': False,\n          'strict': False\n      }\n\nMore information about the arguments you find in the `Pony API documentation`_.\n\nYou can also use the ``database`` settings section for your database setup,\nwhich allows you to use different setups for production, development and\ntesting environments.\n\nJust create create an App for each environment and load specific\nsettings files:\n\n.. code-block:: python\n\n  class App(PonyApp):\n      pass\n\n  with open('settings/default.yml') as defaults:\n    defaults_dict = yaml.load(defaults)\n\n  App.init_settings(defaults_dict)\n\n\n  class ProductionApp(App):\n      pass\n\n\n  with open('settings/production.yml') as settings:\n      settings_dict = yaml.load(settings)\n\n  ProductionApp.init_settings(settings_dict)\n\n\n  class TestApp(App):\n      pass\n\n\n  with open('settings/test.yml') as settings:\n      settings_dict = yaml.load(settings)\n\n  TestApp.init_settings(settings_dict)\n\nThe database configuration in the YAML settings\nfiles, depending on the database you use, could\nlook something like:\n\n.. code-block:: yaml\n\n  database:\n    provider: sqlite\n    filename: app.db\n    create_db: true\n\nIn your start script you setup the database and load\nthe App according to the ``RUN_ENV`` environment variable:\n\n.. code-block:: python\n\n  import os\n  import morepath\n\n  from .app import App, ProductionApp, TestApp\n  from .model import db\n\n\n  def setup_db(app):\n      db_params = app.settings.database.__dict__.copy()\n      db.bind(**db_params)\n      db.generate_mapping(create_tables=True)\n\n  def run():\n    morepath.autoscan()\n\n    if os.getenv('RUN_ENV') == 'production':\n        ProductionApp.commit()\n        app = ProductionApp()\n    elif os.getenv('RUN_ENV') == 'test':\n        TestApp.commit()\n        app = TestApp()\n    else:\n        App.commit()\n        app = App()\n\n    setup_db(app)\n    morepath.run(app)\n\nDetail about the database configuration you find\nin the `PonyOrm documentation`_.\n\n\nSide effects\n------------\n\nIf you want to trigger side effects (like sending an email or\nwriting to filesystem) on database commits you can emit a signal\nin the ``@request.after`` of the view which triggers the side effects.\n\nLike this the side effects will be triggered just before the\ndatabase session gets committed and only if it wasn't rolled back.\n\nThis example uses `more.emit`_:\n\n.. code-block:: python\n\n  @App.json(model=Document, request_method='PUT')\n  def document_update(self, request):\n      self.update(request.json)\n\n      @request.after\n      def after(response):\n          request.app.signal.emit('document_updated', self, request)\n\nAltenatively you can use in your model the PonyORM\n`after_insert()`_, `after_update()`_ or `after_delete()`_\nentity-hooks.\nThis makes sure that the side effect is triggered\n**after** the database session has committed.\n\nThe drawback is that you don't have easy access to the\nrequest or app in the model.\n\n\n.. _Pony: https://ponyorm.com\n.. _Pony API documentation:\n    https://docs.ponyorm.com/api_reference.html#transactions-db-session\n.. _PonyOrm documentation: https://docs.ponyorm.com/api_reference.html#database\n.. _more.emit: https://github.com/morepath/more.emit\n.. _after_insert(): https://docs.ponyorm.com/api_reference.html#after_insert\n.. _after_update(): https://docs.ponyorm.com/api_reference.html#after_update\n.. _after_delete(): https://docs.ponyorm.com/api_reference.html#after_delete\n\n\nCHANGES\n=======\n\n0.4 (2024-03-03)\n----------------\n\n- **Removed**: Drop support for Python 3.4, 3.5, 3.6 and 3.7.\n\n- Add support for Python 3.9, 3.10 and 3.11.\n\n- Fix Flake8.\n\n- Use GitHub Actions for CI.\n\n- Make Python 3.11 the default testing environment.\n\n- Upgrade PonyORM to 0.7.17.\n\n- Show full diffs in the test output.\n\n- Add Editors config and venv to .gitignore.\n\n- Remove report to coveralls.\n\n- Update pre-commit revs.\n\n\n0.3 (2020-04-26)\n----------------\n\n- **Removed**: Removed support for Python 2.\n  \n  You have to upgrade to Python 3 if you want to use this version.\n\n- Added support for Python 3.6, 3.7 and 3.8 and PyPy 3.6.\n\n- Make Python 3.7 the default testing environment.\n\n- Upgrade PonyORM to 0.7.13.\n\n- Add integration for the Black code formatter.\n\n\n\n\n0.2 (2017-07-20)\n----------------\n\n- Upgrade PonyORM to 0.7.2.\n- Use a dictonary for passing parameters to db.bind in examples and tests.\n\n\n0.1 (2017-04-22)\n----------------\n\n- Initial public release.\n",
    "bugtrack_url": null,
    "license": "BSD",
    "summary": "Pony ORM integration in Morepath",
    "version": "0.4",
    "project_urls": {
        "Homepage": "https://github.com/morepath/more.pony"
    },
    "split_keywords": [
        "morepath",
        "pony",
        "orm",
        "ponyorm"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "f5924982114dd22c763dd7a9c2926ad3dd1f9d9a4bdd234fffbd742bb8ae3cee",
                "md5": "96a3fdcc01c6a22ef1891e6890539c87",
                "sha256": "f5ecd1ff2afb1c228f0fcaf70e3618fc1b7b4ef34fd72f4ac806037befd86158"
            },
            "downloads": -1,
            "filename": "more.pony-0.4-py2.py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "96a3fdcc01c6a22ef1891e6890539c87",
            "packagetype": "bdist_wheel",
            "python_version": "py2.py3",
            "requires_python": null,
            "size": 6941,
            "upload_time": "2024-03-03T02:17:40",
            "upload_time_iso_8601": "2024-03-03T02:17:40.212839Z",
            "url": "https://files.pythonhosted.org/packages/f5/92/4982114dd22c763dd7a9c2926ad3dd1f9d9a4bdd234fffbd742bb8ae3cee/more.pony-0.4-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "fa739b16249dc197407a4bf4e55fb0f757fd2381cd95a5042b95cd882e40ff2d",
                "md5": "bc5e084cd66ddd33ab3a529eceab9cb6",
                "sha256": "30afc39f83f3c701a451fd57a8f056f285df9824bff252cc6b0400a3358e7089"
            },
            "downloads": -1,
            "filename": "more.pony-0.4.tar.gz",
            "has_sig": false,
            "md5_digest": "bc5e084cd66ddd33ab3a529eceab9cb6",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 7931,
            "upload_time": "2024-03-03T02:17:42",
            "upload_time_iso_8601": "2024-03-03T02:17:42.408186Z",
            "url": "https://files.pythonhosted.org/packages/fa/73/9b16249dc197407a4bf4e55fb0f757fd2381cd95a5042b95cd882e40ff2d/more.pony-0.4.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-03-03 02:17:42",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "morepath",
    "github_project": "more.pony",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "more.pony"
}
        
Elapsed time: 0.19982s