Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Reformatted PL/SQL flush left so "manage.py sqlall [app] | manage.py …

…dbshell" works with Oracle. Also some PEP8 cleanup.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@9644 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 5257fd222541cb8bd37a7c33d9fea0267374d387 1 parent f1f1d36
Matt Boersma authored December 11, 2008

Showing 1 changed file with 78 additions and 57 deletions. Show diff stats Hide diff stats

  1. 135  django/db/backends/oracle/base.py
135  django/db/backends/oracle/base.py
... ...
@@ -1,7 +1,7 @@
1 1
 """
2 2
 Oracle database backend for Django.
3 3
 
4  
-Requires cx_Oracle: http://www.python.net/crew/atuining/cx_Oracle/
  4
+Requires cx_Oracle: http://cx-oracle.sourceforge.net/
5 5
 """
6 6
 
7 7
 import os
@@ -35,6 +35,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
35 35
 
36 36
 
37 37
 class DatabaseOperations(BaseDatabaseOperations):
  38
+
38 39
     def autoinc_sql(self, table, column):
39 40
         # To simulate auto-incrementing primary keys in Oracle, we have to
40 41
         # create a sequence and a trigger.
@@ -43,26 +44,26 @@ def autoinc_sql(self, table, column):
43 44
         tbl_name = self.quote_name(table)
44 45
         col_name = self.quote_name(column)
45 46
         sequence_sql = """
46  
-            DECLARE
47  
-                i INTEGER;
48  
-            BEGIN
49  
-                SELECT COUNT(*) INTO i FROM USER_CATALOG
50  
-                    WHERE TABLE_NAME = '%(sq_name)s' AND TABLE_TYPE = 'SEQUENCE';
51  
-                IF i = 0 THEN
52  
-                    EXECUTE IMMEDIATE 'CREATE SEQUENCE "%(sq_name)s"';
53  
-                END IF;
54  
-            END;
55  
-            /""" % locals()
  47
+DECLARE
  48
+    i INTEGER;
  49
+BEGIN
  50
+    SELECT COUNT(*) INTO i FROM USER_CATALOG
  51
+        WHERE TABLE_NAME = '%(sq_name)s' AND TABLE_TYPE = 'SEQUENCE';
  52
+    IF i = 0 THEN
  53
+        EXECUTE IMMEDIATE 'CREATE SEQUENCE "%(sq_name)s"';
  54
+    END IF;
  55
+END;
  56
+/""" % locals()
56 57
         trigger_sql = """
57  
-            CREATE OR REPLACE TRIGGER "%(tr_name)s"
58  
-            BEFORE INSERT ON %(tbl_name)s
59  
-            FOR EACH ROW
60  
-            WHEN (new.%(col_name)s IS NULL)
61  
-                BEGIN
62  
-                    SELECT "%(sq_name)s".nextval
63  
-                    INTO :new.%(col_name)s FROM dual;
64  
-                END;
65  
-                /""" % locals()
  58
+CREATE OR REPLACE TRIGGER "%(tr_name)s"
  59
+BEFORE INSERT ON %(tbl_name)s
  60
+FOR EACH ROW
  61
+WHEN (new.%(col_name)s IS NULL)
  62
+    BEGIN
  63
+        SELECT "%(sq_name)s".nextval
  64
+        INTO :new.%(col_name)s FROM dual;
  65
+    END;
  66
+/""" % locals()
66 67
         return sequence_sql, trigger_sql
67 68
 
68 69
     def date_extract_sql(self, lookup_type, field_name):
@@ -118,7 +119,8 @@ def quote_name(self, name):
118 119
         # always defaults to uppercase.
119 120
         # We simplify things by making Oracle identifiers always uppercase.
120 121
         if not name.startswith('"') and not name.endswith('"'):
121  
-            name = '"%s"' % util.truncate_name(name.upper(), self.max_name_length())
  122
+            name = '"%s"' % util.truncate_name(name.upper(),
  123
+                                               self.max_name_length())
122 124
         return name.upper()
123 125
 
124 126
     def random_function_sql(self):
@@ -150,8 +152,8 @@ def sql_flush(self, style, tables, sequences):
150 152
             sql = ['%s %s %s;' % \
151 153
                     (style.SQL_KEYWORD('DELETE'),
152 154
                      style.SQL_KEYWORD('FROM'),
153  
-                     style.SQL_FIELD(self.quote_name(table))
154  
-                     ) for table in tables]
  155
+                     style.SQL_FIELD(self.quote_name(table)))
  156
+                    for table in tables]
155 157
             # Since we've just deleted all the rows, running our sequence
156 158
             # ALTER code will reset the sequence to 0.
157 159
             for sequence_info in sequences:
@@ -179,7 +181,9 @@ def sequence_reset_sql(self, style, model_list):
179 181
                     output.append(query % {'sequence': sequence_name,
180 182
                                            'table': table_name,
181 183
                                            'column': column_name})
182  
-                    break # Only one AutoField is allowed per model, so don't bother continuing.
  184
+                    # Only one AutoField is allowed per model, so don't
  185
+                    # continue to loop
  186
+                    break
183 187
             for f in model._meta.many_to_many:
184 188
                 table_name = self.quote_name(f.m2m_db_table())
185 189
                 sequence_name = get_sequence_name(f.m2m_db_table())
@@ -193,7 +197,8 @@ def start_transaction_sql(self):
193 197
         return ''
194 198
 
195 199
     def tablespace_sql(self, tablespace, inline=False):
196  
-        return "%sTABLESPACE %s" % ((inline and "USING INDEX " or ""), self.quote_name(tablespace))
  200
+        return "%sTABLESPACE %s" % ((inline and "USING INDEX " or ""),
  201
+            self.quote_name(tablespace))
197 202
 
198 203
     def value_to_db_time(self, value):
199 204
         if value is None:
@@ -246,10 +251,16 @@ def _cursor(self, settings):
246 251
             if len(settings.DATABASE_HOST.strip()) == 0:
247 252
                 settings.DATABASE_HOST = 'localhost'
248 253
             if len(settings.DATABASE_PORT.strip()) != 0:
249  
-                dsn = Database.makedsn(settings.DATABASE_HOST, int(settings.DATABASE_PORT), settings.DATABASE_NAME)
250  
-                self.connection = Database.connect(settings.DATABASE_USER, settings.DATABASE_PASSWORD, dsn, **self.options)
  254
+                dsn = Database.makedsn(settings.DATABASE_HOST,
  255
+                                       int(settings.DATABASE_PORT),
  256
+                                       settings.DATABASE_NAME)
  257
+                self.connection = Database.connect(settings.DATABASE_USER,
  258
+                                                   settings.DATABASE_PASSWORD,
  259
+                                                   dsn, **self.options)
251 260
             else:
252  
-                conn_string = "%s/%s@%s" % (settings.DATABASE_USER, settings.DATABASE_PASSWORD, settings.DATABASE_NAME)
  261
+                conn_string = "%s/%s@%s" % (settings.DATABASE_USER,
  262
+                                            settings.DATABASE_PASSWORD,
  263
+                                            settings.DATABASE_NAME)
253 264
                 self.connection = Database.connect(conn_string, **self.options)
254 265
             cursor = FormatStylePlaceholderCursor(self.connection)
255 266
             # Set oracle date to ansi date format.  This only needs to execute
@@ -285,18 +296,19 @@ class OracleParam(object):
285 296
     """
286 297
     Wrapper object for formatting parameters for Oracle. If the string
287 298
     representation of the value is large enough (greater than 4000 characters)
288  
-    the input size needs to be set as NCLOB. Alternatively, if the parameter has
289  
-    an `input_size` attribute, then the value of the `input_size` attribute will
290  
-    be used instead. Otherwise, no input size will be set for the parameter when
291  
-    executing the query.
  299
+    the input size needs to be set as NCLOB. Alternatively, if the parameter
  300
+    has an `input_size` attribute, then the value of the `input_size` attribute
  301
+    will be used instead. Otherwise, no input size will be set for the
  302
+    parameter when executing the query.
292 303
     """
  304
+
293 305
     def __init__(self, param, charset, strings_only=False):
294 306
         self.smart_str = smart_str(param, charset, strings_only)
295 307
         if hasattr(param, 'input_size'):
296 308
             # If parameter has `input_size` attribute, use that.
297 309
             self.input_size = param.input_size
298 310
         elif isinstance(param, basestring) and len(param) > 4000:
299  
-            # Mark any string parameter greater than 4000 characters as an NCLOB.
  311
+            # Mark any string param greater than 4000 characters as an NCLOB.
300 312
             self.input_size = Database.NCLOB
301 313
         else:
302 314
             self.input_size = None
@@ -320,7 +332,8 @@ def _guess_input_sizes(self, params_list):
320 332
         sizes = [None] * len(params_list[0])
321 333
         for params in params_list:
322 334
             for i, value in enumerate(params):
323  
-                if value.input_size: sizes[i] = value.input_size
  335
+                if value.input_size:
  336
+                    sizes[i] = value.input_size
324 337
         self.setinputsizes(*sizes)
325 338
 
326 339
     def _param_generator(self, params):
@@ -341,7 +354,8 @@ def execute(self, query, params=None):
341 354
         query = smart_str(query, self.charset) % tuple(args)
342 355
         self._guess_input_sizes([params])
343 356
         try:
344  
-            return Database.Cursor.execute(self, query, self._param_generator(params))
  357
+            return Database.Cursor.execute(self, query,
  358
+                                           self._param_generator(params))
345 359
         except DatabaseError, e:
346 360
             # cx_Oracle <= 4.4.0 wrongly raises a DatabaseError for ORA-01400.
347 361
             if e.args[0].code == 1400 and not isinstance(e, IntegrityError):
@@ -350,10 +364,10 @@ def execute(self, query, params=None):
350 364
 
351 365
     def executemany(self, query, params=None):
352 366
         try:
353  
-          args = [(':arg%d' % i) for i in range(len(params[0]))]
  367
+            args = [(':arg%d' % i) for i in range(len(params[0]))]
354 368
         except (IndexError, TypeError):
355  
-          # No params given, nothing to do
356  
-          return None
  369
+            # No params given, nothing to do
  370
+            return None
357 371
         # cx_Oracle wants no trailing ';' for SQL statements.  For PL/SQL, it
358 372
         # it does want a trailing ';' but not a trailing '/'.  However, these
359 373
         # characters must be included in the original query in case the query
@@ -364,7 +378,8 @@ def executemany(self, query, params=None):
364 378
         formatted = [self._format_params(i) for i in params]
365 379
         self._guess_input_sizes(formatted)
366 380
         try:
367  
-            return Database.Cursor.executemany(self, query, [self._param_generator(p) for p in formatted])
  381
+            return Database.Cursor.executemany(self, query,
  382
+                                [self._param_generator(p) for p in formatted])
368 383
         except DatabaseError, e:
369 384
             # cx_Oracle <= 4.4.0 wrongly raises a DatabaseError for ORA-01400.
370 385
             if e.args[0].code == 1400 and not isinstance(e, IntegrityError):
@@ -380,10 +395,13 @@ def fetchone(self):
380 395
     def fetchmany(self, size=None):
381 396
         if size is None:
382 397
             size = self.arraysize
383  
-        return tuple([tuple([to_unicode(e) for e in r]) for r in Database.Cursor.fetchmany(self, size)])
  398
+        return tuple([tuple([to_unicode(e) for e in r])
  399
+                      for r in Database.Cursor.fetchmany(self, size)])
384 400
 
385 401
     def fetchall(self):
386  
-        return tuple([tuple([to_unicode(e) for e in r]) for r in Database.Cursor.fetchall(self)])
  402
+        return tuple([tuple([to_unicode(e) for e in r])
  403
+                      for r in Database.Cursor.fetchall(self)])
  404
+
387 405
 
388 406
 def to_unicode(s):
389 407
     """
@@ -394,30 +412,33 @@ def to_unicode(s):
394 412
         return force_unicode(s)
395 413
     return s
396 414
 
  415
+
397 416
 def _get_sequence_reset_sql():
398 417
     # TODO: colorize this SQL code with style.SQL_KEYWORD(), etc.
399 418
     return """
400  
-        DECLARE
401  
-            startvalue integer;
402  
-            cval integer;
403  
-        BEGIN
404  
-            LOCK TABLE %(table)s IN SHARE MODE;
405  
-            SELECT NVL(MAX(%(column)s), 0) INTO startvalue FROM %(table)s;
406  
-            SELECT "%(sequence)s".nextval INTO cval FROM dual;
407  
-            cval := startvalue - cval;
408  
-            IF cval != 0 THEN
409  
-                EXECUTE IMMEDIATE 'ALTER SEQUENCE "%(sequence)s" MINVALUE 0 INCREMENT BY '||cval;
410  
-                SELECT "%(sequence)s".nextval INTO cval FROM dual;
411  
-                EXECUTE IMMEDIATE 'ALTER SEQUENCE "%(sequence)s" INCREMENT BY 1';
412  
-            END IF;
413  
-            COMMIT;
414  
-        END;
415  
-        /"""
  419
+DECLARE
  420
+    startvalue integer;
  421
+    cval integer;
  422
+BEGIN
  423
+    LOCK TABLE %(table)s IN SHARE MODE;
  424
+    SELECT NVL(MAX(%(column)s), 0) INTO startvalue FROM %(table)s;
  425
+    SELECT "%(sequence)s".nextval INTO cval FROM dual;
  426
+    cval := startvalue - cval;
  427
+    IF cval != 0 THEN
  428
+        EXECUTE IMMEDIATE 'ALTER SEQUENCE "%(sequence)s" MINVALUE 0 INCREMENT BY '||cval;
  429
+        SELECT "%(sequence)s".nextval INTO cval FROM dual;
  430
+        EXECUTE IMMEDIATE 'ALTER SEQUENCE "%(sequence)s" INCREMENT BY 1';
  431
+    END IF;
  432
+    COMMIT;
  433
+END;
  434
+/"""
  435
+
416 436
 
417 437
 def get_sequence_name(table):
418 438
     name_length = DatabaseOperations().max_name_length() - 3
419 439
     return '%s_SQ' % util.truncate_name(table, name_length).upper()
420 440
 
  441
+
421 442
 def get_trigger_name(table):
422 443
     name_length = DatabaseOperations().max_name_length() - 3
423 444
     return '%s_TR' % util.truncate_name(table, name_length).upper()

0 notes on commit 5257fd2

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