Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #3115 -- Changed postgresql backend to convert all Unicode stri…

…ngs to bytestrings according to DEFAULT_CHARSET. This is necessary because psycopg1 does not apply database quoting to Unicode strings

git-svn-id: http://code.djangoproject.com/svn/django/trunk@4244 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 252606c711c644d427edf1a5a079d1029f1c6621 1 parent 550781d
Adrian Holovaty authored December 27, 2006

Showing 1 changed file with 33 additions and 0 deletions. Show diff stats Hide diff stats

  1. 33  django/db/backends/postgresql/base.py
33  django/db/backends/postgresql/base.py
@@ -20,6 +20,38 @@
20 20
     # Import copy of _thread_local.py from Python 2.4
21 21
     from django.utils._threading_local import local
22 22
 
  23
+def smart_basestring(s, charset):
  24
+    if isinstance(s, unicode):
  25
+        return s.encode(charset)
  26
+    return s
  27
+
  28
+class UnicodeCursorWrapper(object):
  29
+    """
  30
+    A thin wrapper around psycopg cursors that allows them to accept Unicode
  31
+    strings as params.
  32
+
  33
+    This is necessary because psycopg doesn't apply any DB quoting to
  34
+    parameters that are Unicode strings. If a param is Unicode, this will
  35
+    convert it to a bytestring using DEFAULT_CHARSET before passing it to
  36
+    psycopg.
  37
+    """
  38
+    def __init__(self, cursor, charset):
  39
+        self.cursor = cursor
  40
+        self.charset = charset
  41
+
  42
+    def execute(self, sql, params=()):
  43
+        return self.cursor.execute(sql, [smart_basestring(p, self.charset) for p in params])
  44
+
  45
+    def executemany(self, sql, param_list):
  46
+        new_param_list = [[smart_basestring(p, self.charset) for p in params] for params in param_list]
  47
+        return self.cursor.executemany(sql, new_param_list)
  48
+
  49
+    def __getattr__(self, attr):
  50
+        if self.__dict__.has_key(attr):
  51
+            return self.__dict__[attr]
  52
+        else:
  53
+            return getattr(self.cursor, attr)
  54
+
23 55
 class DatabaseWrapper(local):
24 56
     def __init__(self, **kwargs):
25 57
         self.connection = None
@@ -45,6 +77,7 @@ def cursor(self):
45 77
             self.connection.set_isolation_level(1) # make transactions transparent to all cursors
46 78
         cursor = self.connection.cursor()
47 79
         cursor.execute("SET TIME ZONE %s", [settings.TIME_ZONE])
  80
+        cursor = UnicodeCursorWrapper(cursor, settings.DEFAULT_CHARSET)
48 81
         if settings.DEBUG:
49 82
             return util.CursorDebugWrapper(cursor, self)
50 83
         return cursor

0 notes on commit 252606c

Please sign in to comment.
Something went wrong with that request. Please try again.