From 78217bfc3a22edac3986bd11035b9bff3c186bc9 Mon Sep 17 00:00:00 2001 From: James Bennett Date: Wed, 24 Jan 2007 19:55:43 +0000 Subject: [PATCH] 0.90-bugfixes: Backporting [4244] for those using legacy Django with psycopg1 git-svn-id: http://code.djangoproject.com/svn/django/branches/0.90-bugfixes@4418 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/core/db/backends/postgresql.py | 33 +++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/django/core/db/backends/postgresql.py b/django/core/db/backends/postgresql.py index b1b2d9cb52..fa587f01ca 100644 --- a/django/core/db/backends/postgresql.py +++ b/django/core/db/backends/postgresql.py @@ -9,6 +9,38 @@ import psycopg as Database DatabaseError = Database.DatabaseError +def smart_basestring(s, charset): + if isinstance(s, unicode): + return s.encode(charset) + return s + +class UnicodeCursorWrapper(object): + """ + A thin wrapper around psycopg cursors that allows them to accept Unicode + strings as params. + + This is necessary because psycopg doesn't apply any DB quoting to + parameters that are Unicode strings. If a param is Unicode, this will + convert it to a bytestring using DEFAULT_CHARSET before passing it to + psycopg. + """ + def __init__(self, cursor, charset): + self.cursor = cursor + self.charset = charset + + def execute(self, sql, params=()): + return self.cursor.execute(sql, [smart_basestring(p, self.charset) for p in params]) + + def executemany(self, sql, param_list): + new_param_list = [tuple([smart_basestring(p, self.charset) for p in params]) for params in param_list] + return self.cursor.executemany(sql, new_param_list) + + def __getattr__(self, attr): + if self.__dict__.has_key(attr): + return self.__dict__[attr] + else: + return getattr(self.cursor, attr) + class DatabaseWrapper: def __init__(self): self.connection = None @@ -33,6 +65,7 @@ class DatabaseWrapper: self.connection.set_isolation_level(1) # make transactions transparent to all cursors cursor = self.connection.cursor() cursor.execute("SET TIME ZONE %s", [TIME_ZONE]) + cursor = UnicodeCursorWrapper(cursor, settings.DEFAULT_CHARSET) if DEBUG: return base.CursorDebugWrapper(cursor, self) return cursor