Pony ORM Release 0.6

Starting with this release Pony officially supports Python 3!
In order to have the same Pony code work with both Python 2 and Python 3 we had to make some changes described below.

Deprecation of long type for attributes

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

See more information on this here.

Unicode strings

As you know, Python 3 has some differences from Python 2 when it comes to strings. Python 2 provides two string types – str (byte string) and unicode (unicode string), whereas in Python 3 the str type represents unicode strings and the unicode type has gone.

When we were working on adding Python 3 support to Pony, one of our goals was to have the same Pony entity declarations working on both Python 2 and 3 in the same manner. In order to achieve this we had to make one non-backward compatible change – treat both str and unicode types as they are unicode strings in both Python 2 and 3. Pony just adds unicode as an alias to str in Python 3. When you importing * from pony.orm you will get this alias along with other stuff.

    attr1 = Required(str)
    #   is now the same as
    attr2 = Required(unicode)
    attr3 = Required(LongStr)
    #   is now the same as
    attr4 = Required(LongUnicode)

Before this release, Pony stored values of str and unicode attributes as unicode in the database, but for str attributes it had to convert unicode to byte string on reading from the database. Starting with the Pony Release 0.6 the attributes of str type in Python 2 behave as if they were declared as unicode attributes. There is no difference now if you specify str or unicode as the attribute type – you will have unicode string in Python and in the database.

The same thing is with the LongUnicode and LongStr. LongStr now is an alias to LongUnicode. This type uses unicode in Python and in the database.

Byte sequences

If you need to represent a byte sequence in Python 2, you can use the buffer type. In Python 3 the buffer type has gone, and Pony uses the bytes type which was added in Python 3 to represent binary data. But for the sake of backward compatibility we still keep buffer as an alias to the bytes type in Python 3. If you’re importing * from pony.orm you will get this alias too.

If you want to write code which can run both on Python 2 and Python 3, you should use the buffer type for binary attributes. If your code is for Python 3 only, you can use bytes instead:

    attr1 = Required(buffer) # Python 2 and 3

    attr2 = Required(bytes) # Python 3 only

It would be cool if we could use the bytes type as an alias to buffer in Python 2, but unfortunately it is impossible, because Python 2.6 adds bytes as a synonym for the str type (Btw, there is a good read regarding this decision)

Porting from previous Pony releases to 0.6

In most cases, you don’t need to do anything in order to port your code to Pony ORM 0.6. Pony entity declarations and queries should work correctly by default both in Python 2 and Python 3.

If you declare string attribute as unicode, it will work correctly in Python 2 and Python 3, because Pony adds unicode as an alias to str in Python 3.

If you declare string attribute as str and keep only ASCII data there, it will not require any change and will work both on Python 2 and Python 3. But now that attribute will accept and return unicode values. In Python 2, if you assign an ASCII byte string to such attribute, the value will be automatically converted to unicode.

If you use str attribute type for storing byte strings, you should use buffer or bytes attribute type instead. The bytes type can be used in Python 3 only, it cannot be used correctly in Python 2. The buffer type can be used both in Python 2 and Python 3 with the same meaning. In Python 3 Pony just adds buffer as an alias to bytes.

Declaring Pony entities which work in both Python 2 and 3

It does not matter if you use type str or unicode in you string attributes – both will do the same, because Pony adds unicode as an alias to str in Python 3. But for aesthetical reasons we recommend to keep consistency and assign the same type for all of you string attributes. Starting with this release we prefer to use the str as a string type, because it looks more naturally in Python 3.

For BLOB attributes the preferred type is buffer. In Python 3 Pony adds buffer as an alias to bytes. Don’t use bytes if you want to run your code both in Python 2 and Python 3, because in Python 2 bytes is an alias to str, and has different meaning.

pymysql adapter for MySQL database added

Now Pony can use pymysql adapter in Python 2 and 3. By default, in Python 2, Pony uses MySQLdb for accessing MySQL databases. Now it falls back to pymysql if MySQLdb is not available.

Since MySQLdb doesn’t work in Python 3, here you can use only pymysql adapter.

Documentation updates

Changes and bug fixes

  • Fixed #18: Allow to specify `size` and `unsigned` for int type
  • Fixed #74: Wrong FK column type when using sql_type on foreign ID column
  • Fixed #75: MappingError for self-referenced entities in a many-to-many relationship
  • Fixed #77: Discriminate Pony-generated fields in entities: Attribute.is_implicit field added
  • Fixed #80: “Entity NoneType does not belong to database” when using to_dict
  • 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 #92: without_distinct() and first() do not work together correctly
  • Fixed #94: Aggregated subquery bug fixed

As always, we appreciate your feedback. Try to use Pony in Python 3 and share your experience with us in our email list or by email at team [at] ponyorm.com