Ticket #5543: base.py.diff
File base.py.diff, 6.7 KB (added by , 16 years ago) |
---|
-
base.py
old new 7 7 import os 8 8 import datetime 9 9 import time 10 import string 10 11 11 12 # Oracle takes client-side character set encoding from the environment. 12 13 os.environ['NLS_LANG'] = '.UTF8' … … 251 252 else: 252 253 conn_string = "%s/%s@%s" % (settings.DATABASE_USER, settings.DATABASE_PASSWORD, settings.DATABASE_NAME) 253 254 self.connection = Database.connect(conn_string, **self.options) 255 254 256 cursor = FormatStylePlaceholderCursor(self.connection) 255 257 # Set oracle date to ansi date format. This only needs to execute 256 258 # once when we create a new connection. 257 cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD' 258 259 cursor.execute("ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD'" 260 "NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS.FF'") 259 261 try: 260 262 self.oracle_version = int(self.connection.version.split('.')[0]) 261 263 # There's no way for the DatabaseOperations class to know the … … 280 282 cursor.arraysize = 100 281 283 return cursor 282 284 285 def commit(self): 286 self.connection.commit() 287 283 288 284 289 class OracleParam(object): 285 290 """ … … 314 319 charset = 'utf-8' 315 320 316 321 def _format_params(self, params): 322 if params is None: 323 params = [] 317 324 if isinstance(params, dict): 318 325 result = {} 319 326 for key, value in params.items(): 320 result[smart_str(key, self.charset)] = OracleParam( param, self.charset)327 result[smart_str(key, self.charset)] = OracleParam(value, self.charset) 321 328 return result 322 329 else: 323 330 return tuple([OracleParam(p, self.charset, True) for p in params]) … … 333 340 for key, value in iterator: 334 341 if value.input_size: sizes[key] = value.input_size 335 342 if isinstance(sizes, dict): 336 self.setinputsizes(**sizes)343 return self.setinputsizes(**sizes) 337 344 else: 338 self.setinputsizes(*sizes) 339 345 return self.setinputsizes(*sizes) 346 347 340 348 def _param_generator(self, params): 341 349 if isinstance(params, dict): 342 350 return dict([(k, p.smart_str) for k, p in params.iteritems()]) … … 344 352 return [p.smart_str for p in params] 345 353 346 354 def execute(self, query, params=None): 347 if params is None: 348 params = [] 349 else: 350 params = self._format_params(params) 355 params = self._format_params(params) 351 356 args = [(':arg%d' % i) for i in range(len(params))] 352 357 # cx_Oracle wants no trailing ';' for SQL statements. For PL/SQL, it 353 358 # it does want a trailing ';' but not a trailing '/'. However, these … … 356 361 if query.endswith(';') or query.endswith('/'): 357 362 query = query[:-1] 358 363 query = smart_str(query, self.charset) % tuple(args) 364 #print 'query', query, [x.smart_str for x in params] 365 #print 359 366 self._guess_input_sizes([params]) 360 367 try: 361 368 return Database.Cursor.execute(self, query, self._param_generator(params)) … … 388 395 e = IntegrityError(e.message) 389 396 raise e 390 397 398 399 def callproc(self, name, params=None, keys=None): 400 """ 401 Call a PL/SQL procedure with the given name. 402 The list of parameters must contain one entry for each argument that the procedure expects. 403 The result is a modified copy of the input sequence. 404 Input parameters are left untouched; 405 output and input/output parameters are replaced with possibly new values, 406 and must be initialised as Oracle variables; 407 ex: arg1 = cursor.var(cx_Oracle.STRING), arg1.setvalue('this is an input value'). 408 An optional list of corresponding keys will return a dictionnary instead of a list. 409 """ 410 if isinstance(params, dict): 411 raise('callproc: "params" must be a list, not a dictionnary') 412 params = self._format_params(params) 413 # "keys" is a list of corresponding keys to return a dictionnary of results 414 if keys: 415 if isinstance(keys, list): 416 if len(keys) != len(params): 417 raise('callproc: the number of keys differs from the number of params') 418 else: 419 raise('callproc: "keys" must be a list, not a dictionnary') 420 results = self._guess_input_sizes([params]) 421 try: 422 Database.Cursor.execute( self 423 , "begin %s(%s); end;" % (name, 424 string.join([":arg%d"%i for i in range(len(params))], ',')) 425 , self._param_generator(params) 426 ) 427 except DatabaseError, e: 428 # cx_Oracle <= 4.4.0 wrongly raises a DatabaseError for ORA-01400. 429 if e.message.code == 1400 and type(e) != IntegrityError: 430 e = IntegrityError(e.message) 431 raise e 432 if isinstance(keys, list): 433 return dict([(keys[i], results[i].getvalue()) for i in range(len(keys))]) 434 else: 435 return tuple([result.getvalue() for result in results]) 436 437 438 def callfunc(self, name, returnType, params=None): 439 """ 440 Call a function with the given name. 441 The return type must be a Oracle type; ex: cx_Oracle.STRING 442 The sequence of parameters must contain one entry for each argument that the function expects. 443 The result of the call is the return value of the function. 444 """ 445 if isinstance(params, dict): 446 raise('callfunc: parameters must be in a list, not a dictionnary') 447 if 'cx_Oracle.' not in str(returnType): 448 raise('callfunc: returnType must be a Oracle type') 449 params = self._format_params([self.var(returnType)]+params) 450 results = self._guess_input_sizes([params]) 451 try: 452 Database.Cursor.execute(self 453 , "begin :arg0 := %s(%s); end;" % (name, 454 string.join([":arg%d"%(i+1) for i in range(len(params)-1)], ',')) 455 , self._param_generator(params) 456 ) 457 except DatabaseError, e: 458 # cx_Oracle <= 4.4.0 wrongly raises a DatabaseError for ORA-01400. 459 if e.message.code == 1400 and type(e) != IntegrityError: 460 e = IntegrityError(e.message) 461 raise e 462 return results[0].getvalue() 463 391 464 def fetchone(self): 392 465 row = Database.Cursor.fetchone(self) 393 466 if row is None: