Fix non ascii string handling with composite types, refs #170

This commit is contained in:
Konsta Vesterinen
2015-11-09 17:06:14 +02:00
parent f7b7c5b8b2
commit bed76729a2
4 changed files with 32 additions and 3 deletions

View File

@@ -4,6 +4,12 @@ Changelog
Here you can see the full list of changes between each SQLAlchemy-Utils release.
0.31.3 (2015-11-09)
^^^^^^^^^^^^^^^^^^^
- Fixed non-ascii string handling in composite types (#170)
0.31.2 (2015-10-30)
^^^^^^^^^^^^^^^^^^^

View File

@@ -93,4 +93,4 @@ from .types import ( # noqa
WeekDaysType
)
__version__ = '0.31.2'
__version__ = '0.31.3'

View File

@@ -95,6 +95,7 @@ http://schinckel.net/2014/09/24/using-postgres-composite-types-in-django/
"""
from collections import namedtuple
import six
import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import ARRAY
from sqlalchemy.dialects.postgresql.psycopg2 import PGDialect_psycopg2
@@ -259,7 +260,7 @@ def register_psycopg2_composite(dbapi_connection, composite):
)
def adapt_composite(value):
values = [
adapted = [
adapt(
getattr(value, column.name)
if not isinstance(column.type, TypeDecorator)
@@ -267,10 +268,19 @@ def register_psycopg2_composite(dbapi_connection, composite):
getattr(value, column.name),
PGDialect_psycopg2()
)
).getquoted().decode('utf-8')
)
for column in
composite.columns
]
for value in adapted:
if hasattr(value, 'prepare'):
value.prepare(dbapi_connection)
values = [
value.getquoted().decode(dbapi_connection.encoding)
if six.PY3
else value.getquoted()
for value in adapted
]
return AsIs("(%s)::%s" % (', '.join(values), composite.name))
register_adapter(composite.type_cls, adapt_composite)

View File

@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
import sqlalchemy as sa
from pytest import mark
from sqlalchemy import create_engine
@@ -50,6 +51,18 @@ class TestCompositeTypeWithRegularTypes(TestCase):
assert account.balance.currency == 'USD'
assert account.balance.amount == 15
def test_non_ascii_chars(self):
account = self.Account(
balance=(u'ääöö', 15)
)
self.session.add(account)
self.session.commit()
account = self.session.query(self.Account).first()
assert account.balance.currency == u'ääöö'
assert account.balance.amount == 15
@mark.skipif('i18n.babel is None')
class TestCompositeTypeWithTypeDecorators(TestCase):