From: Mike Bayer Date: Sat, 15 Oct 2011 19:05:51 +0000 (-0400) Subject: - Added client_encoding parameter to create_engine() X-Git-Tag: rel_0_7_3~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5397d953650c3b7728e8285c55c32c5eeb687de9;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - Added client_encoding parameter to create_engine() when the postgresql+psycopg2 dialect is used; calls the psycopg2 set_client_encoding() method with the value upon connect. [ticket:1839] --- diff --git a/CHANGES b/CHANGES index cddd86566f..f18854abdf 100644 --- a/CHANGES +++ b/CHANGES @@ -246,6 +246,11 @@ CHANGES PG. [ticket:2290]. Thanks to Ryan P. Kelly for the patch. + - Added client_encoding parameter to create_engine() + when the postgresql+psycopg2 dialect is used; + calls the psycopg2 set_client_encoding() method + with the value upon connect. [ticket:1839] + - Fixed bug related to [ticket:2141] whereby the same modified index behavior in PG 9 affected primary key reflection on a renamed column. diff --git a/lib/sqlalchemy/dialects/postgresql/psycopg2.py b/lib/sqlalchemy/dialects/postgresql/psycopg2.py index 22487a3590..4ae7e43d30 100644 --- a/lib/sqlalchemy/dialects/postgresql/psycopg2.py +++ b/lib/sqlalchemy/dialects/postgresql/psycopg2.py @@ -76,6 +76,21 @@ Transactions The psycopg2 dialect fully supports SAVEPOINT and two-phase commit operations. +Client Encoding +--------------- + +The psycopg2 dialect accepts a parameter ``client_encoding`` via :func:`.create_engine` +which will call the psycopg2 ``set_client_encoding()`` method for each new +connection:: + + engine = create_engine("postgresql://user:pass@host/dbname", client_encoding='utf8') + +This overrides the encoding specified in the Postgresql client configuration. + +See: http://initd.org/psycopg/docs/connection.html#connection.set_client_encoding + +New in 0.7.3. + Transaction Isolation Level --------------------------- @@ -247,11 +262,13 @@ class PGDialect_psycopg2(PGDialect): } ) - def __init__(self, server_side_cursors=False, use_native_unicode=True, **kwargs): + def __init__(self, server_side_cursors=False, use_native_unicode=True, + client_encoding=None, **kwargs): PGDialect.__init__(self, **kwargs) self.server_side_cursors = server_side_cursors self.use_native_unicode = use_native_unicode self.supports_unicode_binds = use_native_unicode + self.client_encoding = client_encoding if self.dbapi and hasattr(self.dbapi, '__version__'): m = re.match(r'(\d+)\.(\d+)(?:\.(\d+))?', self.dbapi.__version__) @@ -289,21 +306,30 @@ class PGDialect_psycopg2(PGDialect): connection.set_isolation_level(level) def on_connect(self): + fns = [] + if self.client_encoding is not None: + def on_connect(conn): + conn.set_client_encoding(self.client_encoding) + fns.append(on_connect) + if self.isolation_level is not None: - def base_on_connect(conn): + def on_connect(conn): self.set_isolation_level(conn, self.isolation_level) - else: - base_on_connect = None + fns.append(on_connect) if self.dbapi and self.use_native_unicode: extensions = __import__('psycopg2.extensions').extensions - def connect(conn): + def on_connect(conn): extensions.register_type(extensions.UNICODE, conn) - if base_on_connect: - base_on_connect(conn) - return connect + fns.append(on_connect) + + if fns: + def on_connect(conn): + for fn in fns: + fn(conn) + return on_connect else: - return base_on_connect + return None def create_connect_args(self, url): opts = url.translate_connect_args(username='user') diff --git a/test/dialect/test_postgresql.py b/test/dialect/test_postgresql.py index b37344b279..487139102d 100644 --- a/test/dialect/test_postgresql.py +++ b/test/dialect/test_postgresql.py @@ -1622,6 +1622,25 @@ class MiscTest(fixtures.TestBase, AssertsExecutionResults, AssertsCompiledSQL): assert 'will create implicit sequence' in msgs assert 'will create implicit index' in msgs + @testing.only_on('postgresql+psycopg2', 'psycopg2-specific feature') + @engines.close_open_connections + def test_client_encoding(self): + c = testing.db.connect() + current_encoding = c.connection.connection.encoding + c.close() + + # attempt to use an encoding that's not + # already set + if current_encoding == 'UTF8': + test_encoding = 'LATIN1' + else: + test_encoding = 'UTF8' + + e = engines.testing_engine( + options={'client_encoding':test_encoding} + ) + c = e.connect() + eq_(c.connection.connection.encoding, test_encoding) @testing.fails_on('+zxjdbc', "Can't infer the SQL type to use for an instance "