Author Archives: Alexander Kozlovsky

Pony ORM Release 0.7.6

In release 0.7.4 we introduced support of hybrid methods and properties. This change required massive refactoring which lead to some bugs. Current release fixes all new bugs revealed after 0.7.4.

Also in this release some nice features were added. The first is the support of Literal String Interpolation a.k.a f-strings, introduced in Python 3.6. It looks nicely than using of %-interpolation or format method. f-strings use two special bytecode instructions which Pony now able to decompile and translate correctly:

select(f'The age of {s.name} is {s.age}' for s in Student)

The second small feature is a possibility to skip initial rows in query by specifying offset without limit. In order to do this, you can pass None as a limit value, or just omit limit value at all.

Also now it is possible to explicitly case JSON expressions to int, str or float. It may be necessary if you want to mix JSON expressions with expressions of other types in functions like coalesce()

Finally, we introduced @db.on_connect decorator which can be used to set up some connection properties. For example, since release 0.7.4 like in SQLite works as case-sensitive for better compatibility with other database management systems. If for some reason you want to restore the old like behavior, you can set corresponding pragma on SQLite connection:

@db.on_connect(provider='sqlite')
def set_case_insensitive_like(db, connection):
    cursor = connection.cursor()
    cursor.execute('PRAGMA case_sensitive_like = OFF')

Below is the full changelog since 0.7.5:

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
  • @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

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