Changeset 5584
- Timestamp:
- 07/02/07 02:43:36 (1 year ago)
- Files:
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
django/branches/unicode/django/db/backends/oracle/base.py
r5531 r5584 7 7 from django.conf import settings 8 8 from django.db.backends import util 9 from django.utils.datastructures import SortedDict 10 from django.utils.encoding import smart_str, force_unicode 11 import datetime 12 import os 13 14 # Oracle takes client-side character set encoding from the environment. 15 os.environ['NLS_LANG'] = '.UTF8' 9 16 try: 10 17 import cx_Oracle as Database … … 12 19 from django.core.exceptions import ImproperlyConfigured 13 20 raise ImproperlyConfigured, "Error loading cx_Oracle module: %s" % e 14 import datetime15 from django.utils.datastructures import SortedDict16 21 17 22 … … 46 51 self.connection = Database.connect(conn_string, **self.options) 47 52 cursor = FormatStylePlaceholderCursor(self.connection) 48 # default arraysize of 1 is highly sub-optimal53 # Default arraysize of 1 is highly sub-optimal. 49 54 cursor.arraysize = 100 50 # set oracle date to ansi date format55 # Set oracle date to ansi date format. 51 56 cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'") 52 57 cursor.execute("ALTER SESSION SET NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'") … … 79 84 class FormatStylePlaceholderCursor(Database.Cursor): 80 85 """ 81 Django uses "format" (e.g. '%s') style placeholders, but Oracle uses ":var" style. 82 This fixes it -- but note that if you want to use a literal "%s" in a query, 83 you'll need to use "%%s". 86 Django uses "format" (e.g. '%s') style placeholders, but Oracle uses ":var" 87 style. This fixes it -- but note that if you want to use a literal "%s" in 88 a query, you'll need to use "%%s". 89 90 We also do automatic conversion between Unicode on the Python side and 91 UTF-8 -- for talking to Oracle -- in here. 84 92 """ 93 charset = 'utf-8' 94 85 95 def _rewrite_args(self, query, params=None): 86 96 if params is None: 87 97 params = [] 88 98 else: 89 # cx_Oracle can't handle unicode parameters, so cast to str for now 90 for i, param in enumerate(params): 91 if type(param) == unicode: 92 try: 93 params[i] = param.encode('utf-8') 94 except UnicodeError: 95 params[i] = str(param) 99 params = self._format_params(params) 96 100 args = [(':arg%d' % i) for i in range(len(params))] 97 query = query% tuple(args)101 query = smart_str(query, self.charset) % tuple(args) 98 102 # cx_Oracle wants no trailing ';' for SQL statements. For PL/SQL, it 99 103 # it does want a trailing ';' but not a trailing '/'. However, these … … 104 108 return query, params 105 109 110 def _format_params(self, params): 111 if isinstance(params, dict): 112 result = {} 113 charset = self.charset 114 for key, value in params.items(): 115 result[smart_str(key, charset)] = smart_str(value, charset) 116 return result 117 else: 118 return tuple([smart_str(p, self.charset, True) for p in params]) 119 106 120 def execute(self, query, params=None): 107 121 query, params = self._rewrite_args(query, params) … … 111 125 query, params = self._rewrite_args(query, params) 112 126 return Database.Cursor.executemany(self, query, params) 127 128 def fetchone(self): 129 return to_unicode(Database.Cursor.fetchone(self)) 130 131 def fetchmany(self, size=None): 132 if size is None: 133 size = self.arraysize 134 return tuple([tuple([to_unicode(e) for e in r]) for r in Database.Cursor.fetchmany(self, size)]) 135 136 def fetchall(self): 137 return tuple([tuple([to_unicode(e) for e in r]) for r in Database.Cursor.fetchall(self)]) 138 139 def to_unicode(s): 140 """ 141 Convert strings to Unicode objects (and return all other data types 142 unchanged). 143 """ 144 if isinstance(s, basestring): 145 return force_unicode(s) 146 return s 113 147 114 148 def quote_name(name): django/branches/unicode/django/db/backends/oracle/creation.py
r5531 r5584 9 9 'AutoField': 'NUMBER(11)', 10 10 'BooleanField': 'NUMBER(1) CHECK (%(column)s IN (0,1))', 11 'CharField': ' VARCHAR2(%(maxlength)s)',11 'CharField': 'NVARCHAR2(%(maxlength)s)', 12 12 'CommaSeparatedIntegerField': 'VARCHAR2(%(maxlength)s)', 13 13 'DateField': 'DATE', 14 14 'DateTimeField': 'TIMESTAMP', 15 15 'DecimalField': 'NUMBER(%(max_digits)s, %(decimal_places)s)', 16 'FileField': ' VARCHAR2(100)',17 'FilePathField': ' VARCHAR2(100)',16 'FileField': 'NVARCHAR2(100)', 17 'FilePathField': 'NVARCHAR2(100)', 18 18 'FloatField': 'DOUBLE PRECISION', 19 'ImageField': ' VARCHAR2(100)',19 'ImageField': 'NVARCHAR2(100)', 20 20 'IntegerField': 'NUMBER(11)', 21 21 'IPAddressField': 'VARCHAR2(15)', … … 26 26 'PositiveIntegerField': 'NUMBER(11) CHECK (%(column)s >= 0)', 27 27 'PositiveSmallIntegerField': 'NUMBER(11) CHECK (%(column)s >= 0)', 28 'SlugField': ' VARCHAR2(50)',28 'SlugField': 'NVARCHAR2(50)', 29 29 'SmallIntegerField': 'NUMBER(11)', 30 30 'TextField': 'NCLOB',
