summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/engine
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2009-10-26 00:32:39 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2009-10-26 00:32:39 +0000
commit5119ce78b5c47f89a9dfca2a2781cec60551a0e7 (patch)
tree57d266f7e3445be001bc6264223d2e73f256520a /lib/sqlalchemy/engine
parenteb9763febe58655ca0f61fa758925c56b94ece9b (diff)
downloadsqlalchemy-5119ce78b5c47f89a9dfca2a2781cec60551a0e7.tar.gz
- The psycopg2 dialect now uses psycopg2's "unicode extension"
on all new connections, which allows all String/Text/etc. types to skip the need to post-process bytestrings into unicode (an expensive step due to its volume). Other dialects which return unicode natively (pg8000, zxjdbc) also skip unicode post-processing. - String/Text/Unicode types now skip the unicode() check on each result column value if the dialect has detected the DBAPI as returning Python unicode objects natively. This check is issued on first connect using "SELECT CAST 'some text' AS VARCHAR(10)" or equivalent, then checking if the returned object is a Python unicode. This allows vast performance increases for native-unicode DBAPIs, including pysqlite/sqlite3, psycopg2, and pg8000.
Diffstat (limited to 'lib/sqlalchemy/engine')
-rw-r--r--lib/sqlalchemy/engine/default.py21
-rw-r--r--lib/sqlalchemy/engine/strategies.py15
2 files changed, 27 insertions, 9 deletions
diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py
index 12391c005..37afa84ec 100644
--- a/lib/sqlalchemy/engine/default.py
+++ b/lib/sqlalchemy/engine/default.py
@@ -42,6 +42,7 @@ class DefaultDialect(base.Dialect):
# Py2K
supports_unicode_statements = False
supports_unicode_binds = False
+ returns_unicode_strings = False
# end Py2K
name = 'default'
@@ -97,12 +98,32 @@ class DefaultDialect(base.Dialect):
## work around dialects that might change these values
#self.supports_unicode_statements = True
#self.supports_unicode_binds = True
+ #self.returns_unicode_strings = True
def initialize(self, connection):
if hasattr(self, '_get_server_version_info'):
self.server_version_info = self._get_server_version_info(connection)
if hasattr(self, '_get_default_schema_name'):
self.default_schema_name = self._get_default_schema_name(connection)
+ # Py2K
+ self.returns_unicode_strings = self._check_unicode_returns(connection)
+ # end Py2K
+
+ def _check_unicode_returns(self, connection):
+ cursor = connection.connection.cursor()
+ cursor.execute(
+ str(
+ expression.select(
+ [expression.cast(
+ expression.literal_column("'test unicode returns'"),sqltypes.VARCHAR(60))
+ ]).compile(dialect=self)
+ )
+ )
+
+ row = cursor.fetchone()
+ result = isinstance(row[0], unicode)
+ cursor.close()
+ return result
@classmethod
def type_descriptor(cls, typeobj):
diff --git a/lib/sqlalchemy/engine/strategies.py b/lib/sqlalchemy/engine/strategies.py
index ff62b265b..7a8856ba8 100644
--- a/lib/sqlalchemy/engine/strategies.py
+++ b/lib/sqlalchemy/engine/strategies.py
@@ -129,15 +129,12 @@ class DefaultEngineStrategy(EngineStrategy):
engine = engineclass(pool, dialect, u, **engine_args)
if _initialize:
- # some unit tests pass through _initialize=False
- # to help mock engines work
- class OnInit(object):
- def first_connect(self, conn, rec):
- c = base.Connection(engine, connection=conn)
- dialect.initialize(c)
- pool._on_first_connect.insert(0, OnInit())
-
- dialect.visit_pool(pool)
+ dialect.visit_pool(pool)
+
+ def first_connect(conn, rec):
+ c = base.Connection(engine, connection=conn)
+ dialect.initialize(c)
+ pool.add_listener({'first_connect':first_connect})
return engine