~ubuntu-branches/ubuntu/saucy/python-django/saucy-updates

« back to all changes in this revision

Viewing changes to django/db/backends/creation.py

  • Committer: Package Import Robot
  • Author(s): Luke Faraone, Jakub Wilk, Luke Faraone
  • Date: 2013-05-09 15:10:47 UTC
  • mfrom: (1.1.21) (4.4.27 sid)
  • Revision ID: package-import@ubuntu.com-20130509151047-aqv8d71oj9wvcv8c
Tags: 1.5.1-2
[ Jakub Wilk ]
* Use canonical URIs for Vcs-* fields.

[ Luke Faraone ]
* Upload to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
import hashlib
1
2
import sys
2
3
import time
3
4
 
4
5
from django.conf import settings
5
6
from django.db.utils import load_backend
 
7
from django.utils.encoding import force_bytes
 
8
from django.utils.six.moves import input
6
9
 
7
10
# The prefix to put on the default database name when creating
8
11
# the test database.
26
29
        Generates a 32-bit digest of a set of arguments that can be used to
27
30
        shorten identifying names.
28
31
        """
29
 
        return '%x' % (abs(hash(args)) % 4294967296L)  # 2**32
 
32
        h = hashlib.md5()
 
33
        for arg in args:
 
34
            h.update(force_bytes(arg))
 
35
        return h.hexdigest()[:8]
30
36
 
31
37
    def sql_create_model(self, model, style, known_models=set()):
32
38
        """
34
40
            (list_of_sql, pending_references_dict)
35
41
        """
36
42
        opts = model._meta
37
 
        if not opts.managed or opts.proxy:
 
43
        if not opts.managed or opts.proxy or opts.swapped:
38
44
            return [], {}
39
45
        final_output = []
40
46
        table_output = []
50
56
            # Make the definition (e.g. 'foo VARCHAR(30)') for this field.
51
57
            field_output = [style.SQL_FIELD(qn(f.column)),
52
58
                style.SQL_COLTYPE(col_type)]
53
 
            if not f.null:
 
59
            # Oracle treats the empty string ('') as null, so coerce the null
 
60
            # option whenever '' is a possible value.
 
61
            null = f.null
 
62
            if (f.empty_strings_allowed and not f.primary_key and
 
63
                    self.connection.features.interprets_empty_strings_as_nulls):
 
64
                null = True
 
65
            if not null:
54
66
                field_output.append(style.SQL_KEYWORD('NOT NULL'))
55
67
            if f.primary_key:
56
68
                field_output.append(style.SQL_KEYWORD('PRIMARY KEY'))
80
92
 
81
93
        full_statement = [style.SQL_KEYWORD('CREATE TABLE') + ' ' +
82
94
                          style.SQL_TABLE(qn(opts.db_table)) + ' (']
83
 
        for i, line in enumerate(table_output): # Combine and add commas.
 
95
        for i, line in enumerate(table_output):  # Combine and add commas.
84
96
            full_statement.append(
85
 
                '    %s%s' % (line, i < len(table_output)-1 and ',' or ''))
 
97
                '    %s%s' % (line, i < len(table_output) - 1 and ',' or ''))
86
98
        full_statement.append(')')
87
99
        if opts.db_tablespace:
88
100
            tablespace_sql = self.connection.ops.tablespace_sql(
131
143
        """
132
144
        from django.db.backends.util import truncate_name
133
145
 
134
 
        if not model._meta.managed or model._meta.proxy:
 
146
        opts = model._meta
 
147
        if not opts.managed or opts.proxy or opts.swapped:
135
148
            return []
136
149
        qn = self.connection.ops.quote_name
137
150
        final_output = []
138
 
        opts = model._meta
139
151
        if model in pending_references:
140
152
            for rel_class, f in pending_references[model]:
141
153
                rel_opts = rel_class._meta
160
172
        """
161
173
        Returns the CREATE INDEX SQL statements for a single model.
162
174
        """
163
 
        if not model._meta.managed or model._meta.proxy:
 
175
        if not model._meta.managed or model._meta.proxy or model._meta.swapped:
164
176
            return []
165
177
        output = []
166
178
        for f in model._meta.local_fields:
167
179
            output.extend(self.sql_indexes_for_field(model, f, style))
 
180
        for fs in model._meta.index_together:
 
181
            fields = [model._meta.get_field_by_name(f)[0] for f in fs]
 
182
            output.extend(self.sql_indexes_for_fields(model, fields, style))
168
183
        return output
169
184
 
170
185
    def sql_indexes_for_field(self, model, f, style):
171
186
        """
172
187
        Return the CREATE INDEX SQL statements for a single model field.
173
188
        """
174
 
        from django.db.backends.util import truncate_name
175
 
 
176
189
        if f.db_index and not f.unique:
177
 
            qn = self.connection.ops.quote_name
178
 
            tablespace = f.db_tablespace or model._meta.db_tablespace
179
 
            if tablespace:
180
 
                tablespace_sql = self.connection.ops.tablespace_sql(tablespace)
181
 
                if tablespace_sql:
182
 
                    tablespace_sql = ' ' + tablespace_sql
183
 
            else:
184
 
                tablespace_sql = ''
185
 
            i_name = '%s_%s' % (model._meta.db_table, self._digest(f.column))
186
 
            output = [style.SQL_KEYWORD('CREATE INDEX') + ' ' +
187
 
                style.SQL_TABLE(qn(truncate_name(
188
 
                    i_name, self.connection.ops.max_name_length()))) + ' ' +
189
 
                style.SQL_KEYWORD('ON') + ' ' +
190
 
                style.SQL_TABLE(qn(model._meta.db_table)) + ' ' +
191
 
                "(%s)" % style.SQL_FIELD(qn(f.column)) +
192
 
                "%s;" % tablespace_sql]
193
 
        else:
194
 
            output = []
195
 
        return output
 
190
            return self.sql_indexes_for_fields(model, [f], style)
 
191
        else:
 
192
            return []
 
193
 
 
194
    def sql_indexes_for_fields(self, model, fields, style):
 
195
        from django.db.backends.util import truncate_name
 
196
 
 
197
        if len(fields) == 1 and fields[0].db_tablespace:
 
198
            tablespace_sql = self.connection.ops.tablespace_sql(fields[0].db_tablespace)
 
199
        elif model._meta.db_tablespace:
 
200
            tablespace_sql = self.connection.ops.tablespace_sql(model._meta.db_tablespace)
 
201
        else:
 
202
            tablespace_sql = ""
 
203
        if tablespace_sql:
 
204
            tablespace_sql = " " + tablespace_sql
 
205
 
 
206
        field_names = []
 
207
        qn = self.connection.ops.quote_name
 
208
        for f in fields:
 
209
            field_names.append(style.SQL_FIELD(qn(f.column)))
 
210
 
 
211
        index_name = "%s_%s" % (model._meta.db_table, self._digest([f.name for f in fields]))
 
212
 
 
213
        return [
 
214
            style.SQL_KEYWORD("CREATE INDEX") + " " +
 
215
            style.SQL_TABLE(qn(truncate_name(index_name, self.connection.ops.max_name_length()))) + " " +
 
216
            style.SQL_KEYWORD("ON") + " " +
 
217
            style.SQL_TABLE(qn(model._meta.db_table)) + " " +
 
218
            "(%s)" % style.SQL_FIELD(", ".join(field_names)) +
 
219
            "%s;" % tablespace_sql,
 
220
        ]
196
221
 
197
222
    def sql_destroy_model(self, model, references_to_delete, style):
198
223
        """
199
224
        Return the DROP TABLE and restraint dropping statements for a single
200
225
        model.
201
226
        """
202
 
        if not model._meta.managed or model._meta.proxy:
 
227
        if not model._meta.managed or model._meta.proxy or model._meta.swapped:
203
228
            return []
204
229
        # Drop the table now
205
230
        qn = self.connection.ops.quote_name
216
241
 
217
242
    def sql_remove_table_constraints(self, model, references_to_delete, style):
218
243
        from django.db.backends.util import truncate_name
219
 
        if not model._meta.managed or model._meta.proxy:
 
244
        if not model._meta.managed or model._meta.proxy or model._meta.swapped:
220
245
            return []
221
246
        output = []
222
247
        qn = self.connection.ops.quote_name
250
275
            test_db_repr = ''
251
276
            if verbosity >= 2:
252
277
                test_db_repr = " ('%s')" % test_database_name
253
 
            print "Creating test database for alias '%s'%s..." % (
254
 
                self.connection.alias, test_db_repr)
 
278
            print("Creating test database for alias '%s'%s..." % (
 
279
                self.connection.alias, test_db_repr))
255
280
 
256
281
        self._create_test_db(verbosity, autoclobber)
257
282
 
258
283
        self.connection.close()
259
284
        self.connection.settings_dict["NAME"] = test_database_name
260
285
 
261
 
        # Confirm the feature set of the test database
262
 
        self.connection.features.confirm()
263
 
 
264
286
        # Report syncdb messages at one level lower than that requested.
265
287
        # This ensures we don't get flooded with messages during testing
266
288
        # (unless you really ask to be flooded)
323
345
        try:
324
346
            cursor.execute(
325
347
                "CREATE DATABASE %s %s" % (qn(test_database_name), suffix))
326
 
        except Exception, e:
 
348
        except Exception as e:
327
349
            sys.stderr.write(
328
350
                "Got an error creating the test database: %s\n" % e)
329
351
            if not autoclobber:
330
 
                confirm = raw_input(
 
352
                confirm = input(
331
353
                    "Type 'yes' if you would like to try deleting the test "
332
354
                    "database '%s', or 'no' to cancel: " % test_database_name)
333
355
            if autoclobber or confirm == 'yes':
334
356
                try:
335
357
                    if verbosity >= 1:
336
 
                        print ("Destroying old test database '%s'..."
337
 
                               % self.connection.alias)
 
358
                        print("Destroying old test database '%s'..."
 
359
                              % self.connection.alias)
338
360
                    cursor.execute(
339
361
                        "DROP DATABASE %s" % qn(test_database_name))
340
362
                    cursor.execute(
341
363
                        "CREATE DATABASE %s %s" % (qn(test_database_name),
342
364
                                                   suffix))
343
 
                except Exception, e:
 
365
                except Exception as e:
344
366
                    sys.stderr.write(
345
367
                        "Got an error recreating the test database: %s\n" % e)
346
368
                    sys.exit(2)
347
369
            else:
348
 
                print "Tests cancelled."
 
370
                print("Tests cancelled.")
349
371
                sys.exit(1)
350
372
 
351
373
        return test_database_name
361
383
            test_db_repr = ''
362
384
            if verbosity >= 2:
363
385
                test_db_repr = " ('%s')" % test_database_name
364
 
            print "Destroying test database for alias '%s'%s..." % (
365
 
                self.connection.alias, test_db_repr)
 
386
            print("Destroying test database for alias '%s'%s..." % (
 
387
                self.connection.alias, test_db_repr))
366
388
 
367
389
        # Temporarily use a new connection and a copy of the settings dict.
368
390
        # This prevents the production database from being exposed to potential