.. 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"
}