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
- Using standard Python logging for Pony debug messages
- Automatic DISTINCT in queries and Query.without_distinct()
- Deprecation of the long type and new ‘size’ and ‘unsigned’ options of int attributes
- Composite indexes in entity declarations
- Order of saving objects and cyclic chains during saving objects
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