Pony Object Relational Mapper

Overview

Downloads

Downloads Downloads Downloads

Pony Object-Relational Mapper

Pony is an advanced object-relational mapper. The most interesting feature of Pony is its ability to write queries to the database using Python generator expressions and lambdas. Pony analyzes the abstract syntax tree of the expression and translates it into a SQL query.

Here is an example query in Pony:

select(p for p in Product if p.name.startswith('A') and p.cost <= 1000)

Pony translates queries to SQL using a specific database dialect. Currently Pony works with SQLite, MySQL, PostgreSQL and Oracle databases.

By providing a Pythonic API, Pony facilitates fast app development. Pony is an easy-to-learn and easy-to-use library. It makes your work more productive and helps to save resources. Pony achieves this ease of use through the following:

  • Compact entity definitions
  • The concise query language
  • Ability to work with Pony interactively in a Python interpreter
  • Comprehensive error messages, showing the exact part where an error occurred in the query
  • Displaying of the generated SQL in a readable format with indentation

All this helps the developer to focus on implementing the business logic of an application, instead of struggling with a mapper trying to understand how to get the data from the database.

See the example here

Support Pony ORM Development

Pony ORM is Apache 2.0 licensed open source project. If you would like to support Pony ORM development, please consider:

Become a backer or sponsor

Online tool for database design

Pony ORM also has the Entity-Relationship Diagram Editor which is a great tool for prototyping. You can create your database diagram online at https://editor.ponyorm.com, generate the database schema based on the diagram and start working with the database using declarative queries in seconds.

Documentation

Documenation is available at https://docs.ponyorm.org The documentation source is avaliable at https://github.com/ponyorm/pony-doc. Please create new documentation related issues here or make a pull request with your improvements.

License

Pony ORM is released under the Apache 2.0 license.

PonyORM community

Please post your questions on Stack Overflow. Meet the PonyORM team, chat with the community members, and get your questions answered on our community Telegram group. Join our newsletter at ponyorm.org. Reach us on Twitter.

Copyright (c) 2013-2019 Pony ORM. All rights reserved. info (at) ponyorm.org

Comments
  • [BUG] InterfaceError: (0, '')

    [BUG] InterfaceError: (0, '')

    Traceback (most recent call last):
      File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1982, in wsgi_app
        response = self.full_dispatch_request()
      File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1614, in full_dispatch_request
        rv = self.handle_user_exception(e)
      File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1517, in handle_user_exception
        reraise(exc_type, exc_value, tb)
      File "/usr/local/lib/python3.6/dist-packages/flask/_compat.py", line 33, in reraise
        raise value
      File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1612, in full_dispatch_request
        rv = self.dispatch_request()
      File "/usr/local/lib/python3.6/dist-packages/flask/app.py", line 1598, in dispatch_request
        return self.view_functions[rule.endpoint](**req.view_args)
      File "<string>", line 2, in application_list
      File "/usr/local/lib/python3.6/dist-packages/pony/orm/core.py", line 423, in new_func
        finally: db_session.__exit__(exc_type, exc, tb)
      File "/usr/local/lib/python3.6/dist-packages/pony/orm/core.py", line 397, in __exit__
        else: rollback()
      File "<string>", line 2, in rollback
      File "/usr/local/lib/python3.6/dist-packages/pony/utils/utils.py", line 58, in cut_traceback
        return func(*args, **kwargs)
      File "/usr/local/lib/python3.6/dist-packages/pony/orm/core.py", line 326, in rollback
        transact_reraise(RollbackException, exceptions)
      File "/usr/local/lib/python3.6/dist-packages/pony/orm/core.py", line 283, in transact_reraise
        reraise(exc_class, new_exc, tb)
      File "/usr/local/lib/python3.6/dist-packages/pony/utils/utils.py", line 85, in reraise
        try: raise exc.with_traceback(tb)
      File "/usr/local/lib/python3.6/dist-packages/pony/orm/core.py", line 323, in rollback
        try: cache.rollback()
      File "/usr/local/lib/python3.6/dist-packages/pony/orm/core.py", line 1559, in rollback
        cache.close(rollback=True)
      File "/usr/local/lib/python3.6/dist-packages/pony/orm/core.py", line 1573, in close
        try: provider.rollback(connection, cache)
      File "<string>", line 2, in rollback
      File "/usr/local/lib/python3.6/dist-packages/pony/orm/dbapiprovider.py", line 59, in wrap_dbapi_exceptions
        raise InterfaceError(e)
    pony.orm.core.RollbackException: InterfaceError: (0, '')
    

    Looks like it happen when you do nothing to db for some time and then do something. For example, when script waits for http request and when it get it, pony throws the exception. If you do another request after that, everything will be ok.

    I had this issue with aiohttp (but i thought that it's related to threadpool that i used) and flask.

    opened by xunto 17
  • SQL Views

    SQL Views

    I have a db of patients and would like to use an sql view for patient search, is it possible to extend Pony to do this in my code and how(that's if pony can't do this already).

    enhancement 
    opened by noxecane 17
  • Add support for calculated fields

    Add support for calculated fields

    As per this SO question, I'd like to add calculated/derived fields to my entities and then use those fields in calculations, aggregations, etc. I wasn't able to find anything in the docs or examples that indicate that this is supported. Could this kind of thing be supported in the future?

    opened by tonycpsu 16
  • Если вызвать `.flush()` то теряется транзакционная целостность.

    Если вызвать `.flush()` то теряется транзакционная целостность.

    from pony.orm import Database, db_session
    
    db = Database()
    
    
    class TestTable(db.Entity):
        pass
    
    
    def init_database():
        db.bind("sqlite", ":memory:")
        db.generate_mapping(create_tables=True)
    
    
    def clear_database():
        db.drop_all_tables(with_all_data=True)
        db.create_tables()
    
    if __name__ == "__main__":
        init_database()
    
        try:
            with db_session:
                entity = TestTable()
                entity.flush()
                raise ValueError()
        except ValueError as exc:
            print(exc.args)
        with db_session:
            # в транзакции ошибка, а в таблице запись уже есть!
            if len(TestTable.select()) != 0:
                print("Таблица не пуста")
    
        clear_database()
    
        try:
            with db_session:
                entity = TestTable()
                raise ValueError()
        except ValueError as exc:
            print(exc.args)
        with db_session:
            # в транзакции ошибка, а в таблице записи нет, все ок
            if len(TestTable.select()) == 0:
                print("Все в порядке!")
    

    Что как бы очень критичный баг.

    Ну и менее важная проблема - как мне получить id только что созданного элемента?

    bug 
    opened by vladlutkov 15
  • How to filter query inside group statement

    How to filter query inside group statement

    Title probably doesn't describe this, wasn't sure how to explain it.

    Basically, I want to filter my DB columns via url parameters. With a normal select statement, I have this working fine. However I now need to run the filters on a select statement within another select statement and then call .count() on it, the following example will probably explain more.

    def model_with_filters(model, aid, filters):
        query = select(x for x in model)
        for column_name, value in { k: v for k, v in filters.iteritems() if k in model._columns_ and v != ""}.iteritems():
            query = query.filter("lambda x: x.%s == '%s'" % (column_name, value))
        return query.filter("lambda x: x.aff_id== aid")
    
    # This is what I want to do
    select((a, model_with_filters(SendPin, a.aff_id, request.args).count) for a in Affiliate)
    
    
    TypeError: Function 'model_with_filters' cannot be used inside query
    

    However I am not allowed to use a function within the select query. What's the recommended way of being able to apply filters to the count statement if I can't call a function in there?

    Also, using the lambdas like above seems really funky, but it's the only way I could get it to work.

    question 
    opened by JakeAustwick 15
  • "db_session required" exception when working with aync def coroutines

    Hey there. I'm having an issue that reminds #126 which should've been resolved. I'm also using tornado. I've managed to reproduce it with this minimal code:

    https://gist.github.com/amireldor/3c7f1701761d6c92855b868e5df07af0

    I wrap a coroutine (async def) with db_session but an exception is thrown when doing a database action inside the coroutine. Regular wrapped functions or with blocks are fine.

    This is Python 3.6.5 and pony 0.7.6; getting "pony.orm.core.TransactionError: db_session is required when working with the database".

    opened by amireldor 14
  • How to disconnect from db and drop all tables?

    How to disconnect from db and drop all tables?

    Hi, currently I am covering flask app with unit tests and I need to initialize database before each test starts and drop database after test is finished. But seems like there is no "easy" way to do it with PonyORM.

    What I want is something like how it works with sqlalchemy http://pythonhosted.org/Flask-Testing/:

    from flask.ext.testing import TestCase
    
    from myapp import create_app, db
    
    class MyTest(TestCase):
    
        SQLALCHEMY_DATABASE_URI = "sqlite://"
        TESTING = True
    
        def create_app(self):
    
            # pass in test configuration
            return create_app(self)
    
        def setUp(self):
    
            db.create_all()
    
        def tearDown(self):
    
            db.session.remove()
            db.drop_all()
    

    Please advice: how can I disconnect from db and delete it? Is it possible?

    enhancement 
    opened by t4ec 13
  • Efficient lookup in many-many relationship

    Efficient lookup in many-many relationship

    I have the following schema, where the relationship between Executable and Symbol is many-to-many.

        class File(db.Entity):
            loc = Required(str, unique=True)
            tim = Optional(datetime)
    
        class Executable(File):
            sym = Set("Symbol")
    
        class Symbol(db.Entity):
            sig = Required(str, 5000, encoding='utf-8')
            exe = Set(Executable)
    

    A foreign-key table called Executable_Symbol would be created by Pony to store this relationship, but there seems to be no way to check whether a particular relationship exists via the ORM unless I drop down to raw SQL, i.e.

    eid,sid = exe.id,sym.id
    db.select('* from Executable_Symbol where executable=$eid and symbol=$sid ')
    

    I figured the best way of doing this is that if I have a Symbol called sym, and an Executable called exe, I can use the expression:

    exe in sym.exe
    

    But this seems to be very slow. In comparison, accessing the Executable_Symbol table using raw SQL is much faster, but dropping to raw SQL is not very desirable. My application would check this a few hundred thousand times, so every bit of efficiency would be useful.

    Is there a better way to do this?

    thanks!

    enhancement 
    opened by chnrxn 13
  • generate_mapping error

    generate_mapping error

    I use postgres schemas.

    _table_ = (schema, 'molecule')
    

    and then I run generate_mapping(create_tables=True) on existing db with tables I receive:

    DBSchemaError: Table "db_data"."molecule" cannot be created, because table "molecule" (with a different letter case) already exists in the database. Try to delete "molecule" table first.

    but without schemas this works fine.

    bug 
    opened by stsouko 12
  • Cannot use memcached? TransactionRolledBack, 'Object belongs to obsolete cache'

    Cannot use memcached? TransactionRolledBack, 'Object belongs to obsolete cache'

    When I use memcached for cache, it throw the error:

     File "/usr/local/lib/python2.7/dist-packages/pony/orm/core.py", line 871, in __get__
        if not obj._cache_.is_alive: throw(TransactionRolledBack, 'Object belongs to obsolete cache')
    

    How do I use the memcached?

    opened by yetone 12
  • Integer of higher length than 11

    Integer of higher length than 11

    I can't seem to find a way for pony to specify a db int field with a length > 11, so if I try and insert something longer than 11 digits, I get:

    cannot be stored in the database. DataError: 1264 Out of range value for column 'xxx' at row 1

    If I increase the column length manually of the database column, the same problem persists. Any ideas / suggestions?

    opened by JakeAustwick 11
  • Wrong link in the `Parameters of db_session` documentation section

    Wrong link in the `Parameters of db_session` documentation section

    https://docs.ponyorm.org/transactions.html#parameters-of-db-session

    As it was mentioned above db_session() can be used as a decorator or a context manager. It can receive parameters which are described in the API Reference.

    In this paragraph for the API Reference the following link is used https://docs.ponyorm.org/transactions.html#db-session which is incorrect as the correct link is the following https://docs.ponyorm.org/api_reference.html#transactions-db-session

    opened by drew2a 0
  • python-oracledb support.

    python-oracledb support.

    I see the following documentation on https://docs.ponyorm.org/api_reference.html#oracle.

    Pony uses the cx_Oracle driver for connecting to Oracle databases. More information about the parameters which you can use for creating a connection to Oracle database can be found here.

    However, the cx-oracle is deprecated, now python-oracledb should be use instead.

    Is there any plans for update the oracle driver to python-oracledb.

    opened by liudonghua123 1
  • Support for Python 3.11

    Support for Python 3.11

    Are there any plans to support Python 3.11?

    I ran my app's test suite after bumping Python from 3.9.7 to 3.11.0 and got a bunch of the following:

    pony.orm.decompiling.DecompileError: Unsupported operation: RETURN_GENERATOR

    opened by etseidler 6
  • CockroachDB support is broken due to missing method and other issues

    CockroachDB support is broken due to missing method and other issues

    The class PGStrConverter was removed in Jan. https://github.com/ponyorm/pony/commit/071c95c5f77c7682d185900c7630ab722011949f#diff-b703e5fd1906adc8a5be9bbe920[…]9bbbc65a48e35ce5846f0eebcf082L141

    But that class is still being imported in the CockroachDB provider: https://github.com/ponyorm/pony/blob/main/pony/orm/dbproviders/cockroach.py#L20

    So when using CockroachDB, it fails to import that class and crashes.

    I switched to the RC release pony 0.7.15rc1 from Jan 12, 2022 which still has that method intact. But things seem still broken when running the official CockorachDB example: https://www.cockroachlabs.com/docs/stable/build-a-python-app-with-cockroachdb-pony.html#step-4-run-the-python-code

    End up getting this error:

    pony.orm.core.UnexpectedError: Object Account[698658240] cannot be stored in the database. ProgrammingError: value type int doesn't match type uuid of column "id"
    HINT:  you will need to rewrite or cast the expression
    
    opened by dikshant 0
  • pony.orm.dbapiprovider.OperationalError - timed out

    pony.orm.dbapiprovider.OperationalError - timed out

    Hi,

    I implemented some ETL scripts where I partially use SQLAlchemy and for newer implementations I decided to use PonyORM. Since several weeks I have the effect that only those using PonyORM may fail, specially one. Always with the message pony.orm.dbapiprovider.OperationalError - (2003, "Can't connect to MySQL server on 'XXXXXXXXXX' (timed out)")

    I rerun the script again from the command line and the message appears again. At the second manual attempt the script works as expected. Those other scripts with SQLAlchemy never fail, all of the scripts use the same MySQL server as target server.

    The ETL scripts are on a plugin structure, meaning that the connection to the target DB, setting up logfiles, etc. are done within main functions, everything else (gathering data from various sources) is done from a corresponding plugin. That means that for every plugin the starting point is always the same - preparing the environment, connecting to the target, etc.

    I already tried to investigate if there are network connection problems or something similar, but nothing found. I only can say that those scripts usind PonyORM may fail when trying to connect to the target.

    Anyone else had a similar situation?

    Regards, Thomas

    opened by mosesontheweb 0
Releases(v0.7.16)
  • v0.7.16(Jan 27, 2022)

  • v0.7.15(Jan 27, 2022)

    Hi all! We released Pony ORM 0.7.15. This release includes:

    • A long-awaited support of Python 3.10.
    • A possibility to create shared-in memory SQLite databases that can be accessed from multiple threads

    Support of Python 3.10

    Previous versions of PonyORM use Python parser module from Python 2.x to parse Python AST. The support of this module was dropped in Python 3.10. Because of this, Pony ORM switches to new ast module.

    With this change, the support of Python 2.7 and old versions of Python 3 was dropped, and the supported versions now are Python 3.6-Python 3.10

    Shared in-memory SQLite databases

    Previously in-memory SQLite databases are created in Pony ORM by specifying ":memory:" string as a database filename. The database created this way cannot be used in multiple threads. Now it is possible to use ":sharedmemory:" string to create a database that can be accessed from multiple threads.

    Other changes

    • Do not perform optimistic checks when deleting an object (it is OK if it was already deleted by concurrent transaction)
    • Validation of int fields should take into account field size and check that the value is fit into the range
    • More tests for hybrid methods added
    • Fix incorrect assertion check assert t is translator.
    • Fix aggregated query sum(x.field for x in previous_query)
    • #594: Use a clearly synthetic filename when compiling dynamic code to not confuse coverage.py
    • Use DecompileError exception instead of AssertionError when a function cannot be decompiled
    Source code(tar.gz)
    Source code(zip)
    pony-0.7.15-py3-none-any.whl(306.53 KB)
    pony-0.7.15.tar.gz(249.18 KB)
  • v0.7.15rc1(Jan 10, 2022)

    In this release, PonyORM got the support of Python 3.10. The code was rewritten significantly to use the standard Python ast module which comes with Python 3. Now PonyORM works on Python versions 3.7-3.10, and support of Python 2 was ended.

    Bugfixes

    • Do not perform optimistic checks when deleting an object (it is OK if it was already deleted by concurrent transaction)
    • Validation of int fields should take into account field size and check that the value is fit into the range
    • More tests for hybrid methods added
    • Fix incorrect assertion check assert t is translator.
    • Fix aggregated query sum(x.field for x in previous_query)
    • #594: Use a clearly synthetic filename when compiling dynamic code to not confuse coverage.py
    • Use DecompileError exception instead of AssertionError when a function cannot be decompiled.
    Source code(tar.gz)
    Source code(zip)
  • v0.7.14(Nov 23, 2020)

    Features

    • Add Python 3.9 support
    • Allow to use kwargs in select: Entity.select(**kwargs) and obj.collection.select(**kwargs), a feature that was announced but actually missed from 0.7.7
    • Add support for volatile collection attributes that don't throw "Phantom object appeared/disappeared" exceptions

    Bugfixes

    • Fix negative timedelta conversions
    • Pony should reconnect to PostgreSQL when receiving 57P01 error (AdminShutdown)
    • Allow mixing compatible types (like int and float) in coalesce() arguments
    • Support of subqueries in coalesce() arguments
    • Fix using aggregated subqueries in ORDER BY section
    • Fix queries with expressions like (x, y) in ((a, b), (c, d))
    • #451: KeyError for seeds with unique attributes in SessionCache.update_simple_index()
    Source code(tar.gz)
    Source code(zip)
  • v0.7.13(Mar 3, 2020)

  • v0.7.12(Feb 4, 2020)

    Features

    • CockroachDB support added
    • CI testing for SQLite, PostgreSQL & CockroachDB

    Bugfixes

    • Fix translation of getting array items with negative indexes
    • Fix string getitem translation for slices and negative indexes
    • PostgreSQL DISTINCT bug fixed for queries with ORDER BY clause
    • Fix date difference syntax in PostgreSQL
    • Fix casting json to dobule in PostgreSQL
    • Fix count by several columns in PostgreSQL
    • Fix PostgreSQL MIN and MAX expressions on boolean columns
    • Fix determination of interactive mode in PyCharm
    • Fix column definition when sql_default is specified: DEFAULT should be before NOT NULL
    • Relax checks on updating in-memory cache indexes (don't throw CacheIndexError on valid cases)
    • Fix deduplication logic for attribute values
    Source code(tar.gz)
    Source code(zip)
  • v0.7.11(Oct 23, 2019)

    Features

    • #472: Python 3.8 support
    • Support of hybrid functions (inlining simple Python functions into query)
    • #438: support datetime-datetime, datetime-timedelta, datetime+timedelta in queries

    Bugfixes

    • #430: add ON DELETE CASCADE for many-to-many relationships
    • #465: Should reconnect to MySQL on OperationalError 2013 'Lost connection to MySQL server during query'
    • #468: Tuple-value comparisons generate incorrect queries
    • #470 fix PendingDeprecationWarning of imp module
    • Fix incorrect unpickling of objects with Json attributes
    • Check value of discriminator column on object creation if set explicitly
    • Correctly handle Flask current_user proxy when adding new items to collections
    • Some bugs in syntax of aggregated queries were fixed
    • Fix syntax of bulk delete queries
    • Bulk delete queries should clear query results cache so next select will get correct result from the database
    • Fix error message when hybrid method is too complex to decompile
    Source code(tar.gz)
    Source code(zip)
  • v0.7.10(Apr 20, 2019)

    Bugfixes

    • Python3.7 and PyPy decompiling fixes
    • Fix reading NULL from Optional nullable array column
    • Fix handling of empty arrays in queries
    • #415: error message typo
    • #432: PonyFlask - request object can trigger teardown_request without real request
    • Fix GROUP CONCAT separator for MySQL
    Source code(tar.gz)
    Source code(zip)
  • v0.7.9(Jan 21, 2019)

  • v0.7.8(Jan 19, 2019)

    This is a bug fix release

    Bugfixes

    • #414: prefetching Optional relationships fails on 0.7.7
    • Fix a bug caused by incorrect deduplication of column values
    Source code(tar.gz)
    Source code(zip)
  • 0.7.7(Jan 17, 2019)

    Major features

    • Array type support for PostgreSQL and SQLite
    • isinstance() support in queries
    • Support of queries based on collections: select(x for x in y.items)

    Other features

    • Support of Entity.select(**kwargs)
    • Support of SKIP LOCKED option in 'SELECT ... FOR UPDATE'
    • New function make_proxy(obj) to make cros-db_session proxy objects
    • Specify ON DELETE CASCADE/SET NULL in foreign keys
    • Support of LIMIT in SELECT FROM (SELECT ...) type of queries
    • Support for negative JSON array indexes in SQLite

    Improvements

    • Improved query prefetching: use fewer number of SQL queries
    • Memory optimization: deduplication of values recieved from the database in the same session
    • increase DBAPIProvider.max_params_count value

    Bugfixes

    • #405: breaking change with cx_Oracle 7.0: DML RETURNING now returns a list
    • #380: db_session should work with async functions
    • #385: test fails with python3.6
    • #386: release unlocked lock error in SQLite
    • #390: TypeError: writable buffers are not hashable
    • #398: add auto coversion of numpy numeric types
    • #404: GAE local run detection
    • Fix Flask compatibility: add support of LocalProxy object
    • db_session(sql_debug=True) should log SQL commands also during db_session.exit()
    • Fix duplicated table join in FROM clause
    • Fix accessing global variables from hybrid methods and properties
    • Fix m2m collection loading bug
    • Fix composite index bug: stackoverflow.com/questions/53147694
    • Fix MyEntity[obj.get_pk()] if pk is composite
    • MySQL group_concat_max_len option set to max of 32bit platforms to avoid truncation
    • Show all attribute options in show(Entity) call
    • For nested db_session retry option should be ignored
    • Fix py_json_unwrap
    • Other minor fixes
    Source code(tar.gz)
    Source code(zip)
  • 0.7.6(Aug 10, 2018)

    Features since 0.7.5:

    • f-strings support in queries: select(f'{s.name} - {s.age}' for s in Student)
    • #344: It is now possible to specify offset without limit: query.limit(offset=10)
    • #371: Support of explicit casting of JSON expressions to str, int or float
    • @db.on_connect decorator added

    Bugfixes

    • Fix bulk delete bug introduced in 0.7.4
    • #370 Fix memory leak introduced in 0.7.4
    • Now exists() in query does not throw away condition in generator expression: exists(s.gpa > 3 for s in Student)
    • #373: 0.7.4/0.7.5 breaks queries using the in operator to test membership of another query result
    • #374: auto=True can be used with all PrimaryKey types, not only int
    • #369: Make QueryResult looks like a list object again: add concatenation with lists, .shuffle() and .to_list() methods
    • #355: Fix binary primary keys PrimaryKey(buffer) in Python2
    • Interactive mode support for PyCharm console
    • Fix wrong table aliases in complex queries
    • Fix query optimization code for complex queries
    • Fix a bug with hybrid properties that use external functions
    Source code(tar.gz)
    Source code(zip)
  • 0.7.6rc1(Aug 8, 2018)

    This is mostly bugfix release to fix bugs introduced in 0.7.4

    New features

    • f-strings support in queries: select(f'{s.name} - {s.age}' for s in Student)
    • #344: It is now possible to specify offset without limit: query.limit(offset=10)
    • #371: Support of explicit casting of JSON expressions to str, int or float
    • #367: @db.on_connect decorator added

    Bugfixes

    • Fix bulk delete bug introduced in 0.7.4
    • #370 Fix memory leak introduced in 0.7.4
    • Now exists() in query does not throw away condition in generator expression: exists(s.gpa > 3 for s in Student)
    • #373: 0.7.4/0.7.5 breaks queries using the in operator to test membership of another query result
    • #374: auto=True can be used with all PrimaryKey types, not only int
    • #369: Make QueryResult looks like a list object again: add concatenation with lists, .shuffle() and .to_list() methods
    • #355: Fix binary primary keys PrimaryKey(buffer) in Python2
    • Interactive mode support for PyCharm console
    • Fix wrong table aliases in complex queries
    • Fix query optimization code for complex queries
    Source code(tar.gz)
    Source code(zip)
  • 0.7.5(Jul 24, 2018)

  • 0.7.4(Jul 23, 2018)

    Major features

    • Hybrid methods and properties added: https://docs.ponyorm.com/entities.html#hybrid-methods-and-properties
    • Allow to base queries on another queries: select(x.a for x in prev_query if x.b)
    • Added support of Python 3.7
    • Added support of PyPy
    • group_concat() aggregate function added
    • pony.flask subpackage added for integration with Flask

    Other features

    • distinct option added to aggregate functions
    • Support of explicit casting to float and bool in queries

    Improvements

    • Apply @cut_traceback decorator only when pony.MODE is 'INTERACTIVE'

    Bugfixes

    • In SQLite3 LIKE is case sensitive now
    • #249: Fix incorrect mixin used for Timedelta
    • #251: correct dealing with qualified table names
    • #301: Fix aggregation over JSON Column
    • #306: Support of frozenset constants added
    • #308: Fixed an error when assigning JSON attribute value to the same attribute: obj.json_attr = obj.json_attr
    • #313: Fix missed retry on exception raised during db_session.__exit__
    • #314: Fix AttributeError: 'NoneType' object has no attribute 'seeds'
    • #315: Fix attribute lifting for JSON attributes
    • #321: Fix KeyError on obj.delete()
    • #325: duplicating percentage sign in raw SQL queries without parameters
    • #331: Overriding __len__ in entity fails
    • #336: entity declaration serialization
    • #357: reconnect after PostgreSQL server closed the connection unexpectedly
    • Fix Python implementation of between() function and rename arguments: between(a, x, y) -> between(x, a, b)
    • Fix retry handling: in PostgreSQL and Oracle an error can be raised during commit
    • Fix optimistic update checks for composite foreign keys
    • Don't raise OptimisticCheckError if db_session is not optimistic
    • Handling incorrect datetime values in MySQL
    • Improved ImportError exception messages when MySQLdb, pymysql, psycopg2 or psycopg2cffi driver was not found
    • desc() function fixed to allow reverse its effect by calling desc(desc(x))
    • __contains__ method should check if objects belong to the same db_session
    • Fix pony.MODE detection; mod_wsgi detection according to official doc
    • A lot of inner fixes
    Source code(tar.gz)
    Source code(zip)
  • 0.7.3(Oct 23, 2017)

    New features

    • where() method added to query
    • coalesce() function added
    • between(x, a, b) function added
    • #295: Add _table_options_ for entity class to specify engine, tablespace, etc.
    • Make debug flag thread-local
    • sql_debugging context manager added
    • sql_debug and show_values arguments to db_session added
    • set_sql_debug function added as alias to (to be deprecated) sql_debug function
    • Allow db_session to accept ddl parameter when used as context manager
    • Add optimistic=True option to db_session
    • Skip optimistic checks for queries in db_session with serializable=True
    • fk_name option added for attributes in order to specify foreign key name
    • #280: Now it's possible to specify timeout option, as well as pass other keyword arguments for sqlite3.connect function
    • Add support of explicit casting to int in queries using int() function
    • Added modulo division % native support in queries

    Bugfixes

    • Fix bugs with composite table names
    • Fix invalid foreign key & index names for tables which names include schema name
    • For queries like select(x for x in MyObject if not x.description) add "OR x.info IS NULL" for nullable string columns
    • Add optimistic checking for delete() method
    • Show updated attributes when OptimisticCheckError is being raised
    • Fix incorrect aliases in nested queries
    • Correctly pass exception from user-defined functions in SQLite
    • More clear error messages for UnrepeatableReadError
    • Fix db_session(strict=True) which was broken in 2d3afb24
    • Fixes #170: Problem with a primary key column used as a part of another key
    • Fixes #223: incorrect result of getattr(entity, attrname) when the same lambda applies to different entities
    • Fixes #266: Add handler to "pony.orm" logger does not work
    • Fixes #278: Cascade delete error: FOREIGN KEY constraint failed, with complex entity relationships
    • Fixes #283: Lost Json update immediately after object creation
    • Fixes #284: query.order_by() orders Json numbers like strings
    • Fixes #288: Expression text parsing issue in Python 3
    • Fixes #293: translation of if-expressions in expression
    • Fixes #294: Real stack traces swallowed within IPython shell
    • Collection.count() method should check if session is alive
    • Set obj._session_cache_ to None after exiting from db session for better garbage collection
    • Unload collections which are not fully loaded after exiting from db session for better garbage collection
    • Raise on unknown options for attributes that are part of relationship
    Source code(tar.gz)
    Source code(zip)
  • 0.7.2(Jul 17, 2017)

    New features

    • All arguments of db.bind() can be specified as keyword arguments. Previously Pony required the first positional argument which specified the database provider. Now you can pass all the database parameters using the dict: db.bind(**db_params). See https://docs.ponyorm.com/api_reference.html#Database.bind
    • The optimistic attribute option is added https://docs.ponyorm.com/api_reference.html#cmdoption-arg-optimistic

    Bugfixes

    • Fixes #219: when a database driver raises an error, sometimes this error was masked by the 'RollbackException: InterfaceError: connection already closed' exception. This happened because on error, Pony tried to rollback transaction, but the connection to the database was already closed and it masked the initial error. Now Pony displays the original error which helps to understand the cause of the problem.
    • Fixes #276: Memory leak
    • Fixes the all declaration. Previously IDEs, such as PyCharm, could not understand what is going to be imported by 'from pony.orm import *'. Now it works fine.
    • Fixes #232: negate check for numeric expressions now checks if value is zero or NULL
    • Fixes #238, fixes #133: raise TransactionIntegrityError exception instead of AssertionError if obj.collection.create(**kwargs) creates a duplicate object
    • Fixes #221: issue with unicode json path keys
    • Fixes bug when discriminator column is used as a part of a primary key
    • Handle situation when SQLite blob column contains non-binary value
    Source code(tar.gz)
    Source code(zip)
  • 0.7.1(Jan 10, 2017)

    New features

    • New warning DatabaseContainsIncorrectEmptyValue added, it is raised when the required attribute is empty during loading an entity from the database

    Bugfixes

    • Fixes #216: Added Python 3.6 support
    • Fixes #203: subtranslator should use argnames from parent translator
    • Change a way aliases in SQL query are generated in order to fix a problem when a subquery alias masks a base query alias
    • Volatile attribute bug fixed
    • Fix creation of self-referenced foreign keys - before this Pony didn't create the foreign key for self-referenced attributes
    • Bug fixed: when required attribute is empty the loading from the database shouldn't raise the validation error. Now Pony raises the warning DatabaseContainsIncorrectEmptyValue
    • Throw an error with more clear explanation when a list comprehension is used inside a query instead of a generator expression: "Use generator expression (... for ... in ...) instead of list comprehension [... for ... in ...] inside query"
    Source code(tar.gz)
    Source code(zip)
  • 0.7(Oct 11, 2016)

    Starting with this release Pony ORM is release under the Apache License, Version 2.0.

    New features

    • Added getattr() support in queries: https://docs.ponyorm.com/api_reference.html#getattr

    Backward incompatible changes

    • #159: exceptions happened during flush() should not be wrapped with CommitException

    Before this release an exception that happened in a hook(https://docs.ponyorm.com/api_reference.html#entity-hooks), could be raised in two ways - either wrapped into the CommitException or without wrapping. It depended if the exception happened during the execution of flush() or commit() function on the db_session exit. Now the exception happened inside the hook never will be wrapped into the CommitException.

    Bugfixes

    • #190: Timedelta is not supported when using pymysql
    Source code(tar.gz)
    Source code(zip)
  • 0.6.6(Aug 22, 2016)

    New features

    • Added native JSON data type support in all supported databases: https://docs.ponyorm.com/json.html

    Backward incompatible changes

    • Dropped Python 2.6 support

    Improvements

    • #179 Added the compatibility with PYPY using psycopg2cffi
    • Added an experimental @db_session strict parameter: https://docs.ponyorm.com/transactions.html#strict

    Bugfixes

    • #182 - LEFT JOIN doesn't work as expected for inherited entities when foreign key is None
    • Some small bugs were fixed
    Source code(tar.gz)
    Source code(zip)
  • 0.6.5(Apr 4, 2016)

    Improvements

    • Fixes #172: Query prefetch() method should load specified lazy attributes right in the main query if possible

    Bugfixes

    • Fixes #168: Incorrect caching when slicing the same query multiple times
    • Fixes #169: When py_check() returns False, Pony should truncate too large values in resulting ValueError message
    • Fixes #171: AssertionError when saving changes of multiple objects
    • Fixes #176: Autostripped strings are not validated correctly for Required attributes

    See blog post for more detailed information: https://blog.ponyorm.com/2016/04/04/pony-orm-release-0-6-5/

    Source code(tar.gz)
    Source code(zip)
  • 0.6.4(Feb 10, 2016)

    Pony ORM Release 0.6.4 (2016-02-10)

    This release brings no new features, has no backward incompatible changes, only bug fixes. If you are using obj.flush() method in your code we recommend you to upgrade to 0.6.4 release.

    • Fixed #161: 0.6.3 + obj.flush(): after_insert, after_update & after_delete hooks do not work
    Source code(tar.gz)
    Source code(zip)
  • 0.6.3(Feb 5, 2016)

    This release was intended to fix the behavior of obj.flush(), but failed to do it in a proper way. Please skip this release and update to 0.6.4 if you are using obj.flush() method.

    • Fixed #138: Incorrect behavior of obj.flush(): assertion failed after exception
    • Fixed #157: Incorrect transaction state after obj.flush() caused “release unlocked lock” error in SQLite
    • Fixed #151: SQLite + upper() or lower() does not work as expected

    #138: Incorrect behavior of obj.flush(): assertion failed after exception,

    #157: Incorrect transaction state after obj.flush() caused “release unlocked lock” error in SQLite

    These are long-standing bugs, but they were discovered just recently. The bugs were caused by incorrect implementation of obj.flush() method. In the same time the global flush() function worked correctly. Before this fix the method obj.flush() didn’t call before_xxx and after_xxx hooks. In some cases it led to assertion error or some other errors when using SQLite.

    Now both bugs are fixed and the method obj.flush() works properly.

    #151: SQLite + upper() or lower() does not work as expected

    Since SQLite does not support Unicode operations, the upper() and lower() SQL functions do not work for non-ascii symbols.

    Starting with this release Pony registers two additional unicode-aware functions in SQLite: py_upper() and py_lower(), and uses these functions instead of the standard upper() and lower() functions:

    >>> select(p.id for p in Person if p.name.upper() == 'John')[:]
    

    SQLite query:

    SELECT "p"."id"
    FROM "Person" "p"
    WHERE py_upper("p"."name") = 'John'
    

    For other databases Pony still uses standard upper() and lower() functions.

    Source code(tar.gz)
    Source code(zip)
  • 0.6.2(Jan 11, 2016)

    Pony ORM Release 0.6.2 (2016-01-11)

    Blogpost: https://blog.ponyorm.com/2016/01/11/pony-orm-release-0-6-2/

    The documentation was moved from this repo to a separate one at https://github.com/ponyorm/pony-doc The compiled version can be found at https://docs.ponyorm.com

    New features

    • Python 3.5 support
    • #132, #145: raw_sql() function was added
    • #126: Ability to use @db_session with generator functions
    • #116: Add support to select by UUID
    • Ability to get string SQL statement using the Query.get_sql() method
    • New function delete(gen) and Query.delete(bulk=False)
    • Now it is possible to override Entity.init() and declare custom entity methods

    Backward incompatible changes

    • Normalizing table names for symmetric relationships
    • Autostrip - automatically remove leading and trailing characters

    Bugfixes

    • #87: Pony fails with pymysql installed as MySQLdb
    • #118: Pony should reconnect if previous connection was created before process was forked
    • #121: Unable to update value of unique attribute
    • #122: AssertionError when changing part of a composite key
    • #127: a workaround for incorrect pysqlite locking behavior
    • #136: Cascade delete does not work correctly for one-to-one relationships
    • #141, #143: remove restriction on adding new methods to entities
    • #142: Entity.select_random() AssertionError
    • #147: Add 'atom_expr' symbol handling for Python 3.5 grammar
    Source code(tar.gz)
    Source code(zip)
  • 0.6.1(Feb 20, 2015)

    • Closed #65: Now the select(), filter(), order_by(), page(), limit(), random() methods can be applied to collection attributes
    • Closed #105: Now you can pass globals and locals to the select() function
    • Improved inheritance support in queries: select(x for x in BaseClass if x.subclass_attr == y)
    • Now it is possible to do db.insert(SomeEntity, column1=x, column2=y) instead of db.insert(SomeEntity._table_, column1=x, column2=y)
    • Discriminator attribute can be part of the composite index
    • Now it is possible to specify the attribute name instead of the attribute itself in composite index
    • Query statistics: global_stats_lock is deprecated, just use global_stats property without any locking
    • New load() method for entity instances which retrieves all unloaded attributes except collections
    • New load() method for collections, e.g. customer.orders.load()
    • Enhanced error message when descendant classes declare attributes with the same name
    • Fixed #98: Composite index can include attributes of base entity
    • Fixed #106: incorrect loading of object which consists of primary key only
    • Fixed pony.converting.check_email()
    • Prefetching bug fixed: if collection is already fully loaded it shouldn't be loaded again
    • Deprecated Entity.order_by(..) method was removed. Use Entity.select().order_by(...) instead
    • Various performance enhancements
    • Multiple bugs were fixed
    Source code(tar.gz)
    Source code(zip)
  • 0.6(Nov 5, 2014)

    Changes since Pony ORM 0.6rc3:

    • Fixed #94: Aggregated subquery bug fixed

    Short description

    • Official support of Python 3 added!
    • As a string attribute type, use str instead of unicode for compatibility with Python 3
    • Use int with size=64 option instead of long for compatibility with Python 3
    • In Python 3, use pure-python pymysql adapter instead of MySQLdb
    • Multiple bugfixes and optimizations since 0.5.4 release

    Full description:

    http://blog.ponyorm.com/2014/11/05/pony-orm-release-0-6/

    Source code(tar.gz)
    Source code(zip)
  • 0.6rc3(Oct 30, 2014)

    Bugfixes

    • Fixed #18: Allow to specify size and unsigned for int type
    • Fixed #77: Discriminate Pony-generated fields in entities: Attribute.is_implicit field added
    • Fixed #83: Entity.get() should issue LIMIT 2 when non-unique criteria used for search
    • Fixed #84: executing db.insert() should turn off autocommit and begin transaction
    • Fixed #88: composite_index(*attrs) added to support non-unique composite indexes
    • Fixed #89: IN / NOT IN clauses works different with empty sequence
    • Fixed #90: Do not automatically add "distinct" if query.first() used
    • Fixed #91: document automatic "distinct" behaviour and also .without_distinct()
    • Fixed #92: without_distinct() and first() do not work together correctly

    Deprecation of attribute long type

    • size and unsigned options for int attributes link

    Since the long type has gone in Python 3, the long type is deprecated in Pony now. Instead of long you should use the int type and specify the size option:

        class MyEntity(db.Entity):
            attr1 = Required(long) # deprecated
            attr2 = Required(int, size=64) # new way for using BIGINT type in the database
    
    Source code(tar.gz)
    Source code(zip)
  • 0.6rc2(Oct 10, 2014)

  • 0.6rc1(Oct 8, 2014)

    Blog post: http://blog.ponyorm.com/2014/10/08/pony-orm-0-6-release-candidate-1

    New features:

    • Python 3 support
    • pymysql adapter support for MySQL databases

    Backward incompatible changes

    Now Pony treats both str and unicode attribute types as they are unicode strings in both Python 2 and 3. So, the attribute declaration attr = Required(str) is equal to attr = Required(unicode) in Python 2 and 3. The same thing is with LongStr and LongUnicode - both of them are represented as unicode strings now.

    For the sake of backward compatibility Pony adds unicode as an alias to str and buffer as an alias to bytes in Python 3.

    Other changes and bug fixes

    • Fixes #74: Wrong FK column type when using sql_type on foreign ID column
    • Fixes #75: MappingError for self-referenced entities in a many-to-many relationship
    • Fixes #80: “Entity NoneType does not belong to database” when using to_dict
    Source code(tar.gz)
    Source code(zip)
  • 0.5.4(Sep 22, 2014)

    New functions and methods:

    • pony.orm.serialization module with the to_dict() and to_json() functions was added. Before this release you could use the to_dict() method of an entity instance in order to get a key-value dictionary structure for a specific entity instance. Sometimes you might need to serialize not only the instance itself, but also the instance's related objects. In this case you can use the to_dict() function from the pony.orm.serialization module.
      • to_dict() - receives an entity instance or a list of instances and returns a dictionary structure which keeps the passed object(s) and immediate related objects
      • to_json() – uses to_dict() and returns JSON representation of the to_dict() result
    • Query.prefetch() – allows to specify which related objects or attributes should be loaded from the database along with the query result . Example:
          select(s for s in Student).prefetch(Group, Department, Student.courses)
    
    • obj.flush() – allows flush a specific entity to the database
    • obj.get_pk() – return the primary key value for an entity instance
    • py_check parameter for attributes added. This parameter allows you to specify a function which will be used for checking the value before it is assigned to the attribute. The function should return True/False or can raise ValueError exception if the check failed. Example:
        class Student(db.Entity):
            name = Required(unicode)
            gpa = Required(float, py_check=lambda val: val >= 0 and val <= 5)
    

    New types:

    • time and timedelta – now you can use these types for attribute declaration. Also you can use timedelta and a combination of datetime + timedelta types inside queries.

    New hooks:

    • after_insert, after_update, after_delete - these hooks are called when an object was inserted, updated or deleted in the database respectively (link)

    New features:

    • Added support for pymysql – pure Python MySQL client. Currently it is used as a fallback for MySQLdb interface

    Other changes and bug fixes

    • obj.order_by() method is deprecated, use Entity.select().order_by() instead
    • obj.describe() now displays composite primary keys
    • Fixes #50: PonyORM does not escape _ and % in LIKE queries
    • Fixes #51: Handling of one-to-one relations in declarative queries
    • Fixes #52: An attribute without a column should not have rbits & wbits
    • Fixes #53: Column generated at the wrong side of "one-to-one" relationship
    • Fixes #55: obj.to_dict() should do flush at first if the session cache is modified
    • Fixes #57: Error in to_dict() when to-one attribute value is None
    • Fixes #70: EntitySet allows to add and remove None
    • Check that the entity name starts with a capital letter and throw exception if it is not then raise the ERDiagramError: Entity class name should start with a capital letter exception
    Source code(tar.gz)
    Source code(zip)
Prisma Client Python is an auto-generated and fully type-safe database client

Prisma Client Python is an unofficial implementation of Prisma which is a next-generation ORM that comes bundled with tools, such as Prisma Migrate, which make working with databases as easy as possi

Robert Craigie 930 Jan 08, 2023
A curated list of awesome tools for SQLAlchemy

Awesome SQLAlchemy A curated list of awesome extra libraries and resources for SQLAlchemy. Inspired by awesome-python. (See also other awesome lists!)

Hong Minhee (洪 民憙) 2.5k Dec 31, 2022
A Python Library for Simple Models and Containers Persisted in Redis

Redisco Python Containers and Simple Models for Redis Description Redisco allows you to store objects in Redis. It is inspired by the Ruby library Ohm

sebastien requiem 436 Nov 10, 2022
A PostgreSQL or SQLite orm for Python

Prom An opinionated lightweight orm for PostgreSQL or SQLite. Prom has been used in both single threaded and multi-threaded environments, including en

Jay Marcyes 18 Dec 01, 2022
Piccolo - A fast, user friendly ORM and query builder which supports asyncio.

A fast, user friendly ORM and query builder which supports asyncio.

919 Jan 04, 2023
Pony Object Relational Mapper

Downloads Pony Object-Relational Mapper Pony is an advanced object-relational mapper. The most interesting feature of Pony is its ability to write que

3.1k Jan 01, 2023
A simple project to explore the number of GCs when doing basic ORM work.

Question: Does Python do extremely too many GCs for ORMs? YES, OMG YES. Check this out Python Default GC Settings: SQLAlchemy - 20,000 records in one

Michael Kennedy 26 Jun 05, 2022
SQLModel is a library for interacting with SQL databases from Python code, with Python objects.

SQLModel is a library for interacting with SQL databases from Python code, with Python objects. It is designed to be intuitive, easy to use, highly compatible, and robust.

Sebastián Ramírez 9.1k Dec 31, 2022
Bringing Async Capabilities to django ORM

Bringing Async Capabilities to django ORM

Skander BM 119 Dec 01, 2022
Object mapper for Amazon's DynamoDB

Flywheel Build: Documentation: http://flywheel.readthedocs.org/ Downloads: http://pypi.python.org/pypi/flywheel Source: https://github.com/stevearc/fl

Steven Arcangeli 128 Dec 31, 2022
ORM for Python for PostgreSQL.

New generation (or genius) ORM for Python for PostgreSQL. Fully-typed for any query with Pydantic and auto-model generation, compatible with any sync or async driver

Yan Kurbatov 3 Apr 13, 2022
A very simple CRUD class for SQLModel! ✨

Base SQLModel A very simple CRUD class for SQLModel! ✨ Inspired on: Full Stack FastAPI and PostgreSQL - Base Project Generator FastAPI Microservices I

Marcelo Trylesinski 40 Dec 14, 2022
The Orator ORM provides a simple yet beautiful ActiveRecord implementation.

Orator The Orator ORM provides a simple yet beautiful ActiveRecord implementation. It is inspired by the database part of the Laravel framework, but l

Sébastien Eustace 1.4k Jan 01, 2023
Tortoise ORM is an easy-to-use asyncio ORM inspired by Django.

Tortoise ORM was build with relations in mind and admiration for the excellent and popular Django ORM. It's engraved in it's design that you are working not with just tables, you work with relational

Tortoise 3.3k Jan 07, 2023
A single model for shaping, creating, accessing, storing data within a Database

'db' within pydantic - A single model for shaping, creating, accessing, storing data within a Database Key Features Integrated Redis Caching Support A

Joshua Jamison 178 Dec 16, 2022
Rich Python data types for Redis

Created by Stephen McDonald Introduction HOT Redis is a wrapper library for the redis-py client. Rather than calling the Redis commands directly from

Stephen McDonald 281 Nov 10, 2022
A pure Python Database Abstraction Layer

pyDAL pyDAL is a pure Python Database Abstraction Layer. It dynamically generates the SQL/noSQL in realtime using the specified dialect for the databa

440 Nov 13, 2022
A Python Object-Document-Mapper for working with MongoDB

MongoEngine Info: MongoEngine is an ORM-like layer on top of PyMongo. Repository: https://github.com/MongoEngine/mongoengine Author: Harry Marr (http:

MongoEngine 3.9k Dec 30, 2022
The Python SQL Toolkit and Object Relational Mapper

SQLAlchemy The Python SQL Toolkit and Object Relational Mapper Introduction SQLAlchemy is the Python SQL toolkit and Object Relational Mapper that giv

mike bayer 3.5k Dec 29, 2022
A database migrations tool for TortoiseORM, ready to production.

Aerich Introduction Aerich is a database migrations tool for Tortoise-ORM, which is like alembic for SQLAlchemy, or like Django ORM with it's own migr

Tortoise 596 Jan 06, 2023