Pony ORM Releases 0.7.4 & 0.7.5

In these releases we add support of Python 3.7 and PyPy. Also we changed PonyORM internals significantly in order to add two long-demanded features. The first is hybrid methods and properties. Now it is possible to define one-line method or property in entity class and use it inside declarative queries. This way it is possible to re-use complex expressions between different queries:

class Person(db.Entity):
    first_name = Required(str)
    last_name = Required(str)
    country = Required(str)
    age = Required(int)

    @property
    def full_name(self):
        return self.first_name + self.last_name

    @property
    def is_adult(self):
        return self.age > 18

...

query = select(p for p in Person if p.is_adult)

The second feature is the possibility to base query on a previous query. This way it is possible to construct complex queries gradually. In previous versions of Pony it was possible to add conditions by using query.filter method:

query2 = query.filter(lambda person: person.country == 'USA')

but query.filter function cannot change the result type of query. Now you have full flexibility for making your query:

query3 = select(x.full_name for x in query2 if x.last_name.startswith('A'))

Implementing this two features was not easy, because SQL and Python have different namespace rules, and mapping Python name to SQL aliases is a non-trivial task for complex queries.

Also we added a pony.flask subpackage wich provide integration with Flask, so extensions like Flask-Login can work with Pony.

From now on we will concentrate on migration tool and hopefully release it soon.

Here is the detailed changelog:

Pony ORM Release 0.7.4 (2018-07-23)

Major features

  • Hybrid methods and properties added
  • 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

Pony ORM Release 0.7.5 (2018-07-24)

Bugfixes

  • query.where and query.filter method bug introduced in 0.7.4 was fixed