Code

Ticket #14098: inspect-skip.diff

File inspect-skip.diff, 9.5 KB (added by adamv, 4 years ago)
Line 
1diff --git a/django/core/management/commands/inspectdb.py b/django/core/management/commands/inspectdb.py
2index e45f22c..f606b41 100644
3--- a/django/core/management/commands/inspectdb.py
4+++ b/django/core/management/commands/inspectdb.py
5@@ -11,6 +11,9 @@ class Command(NoArgsCommand):
6         make_option('--database', action='store', dest='database',
7             default=DEFAULT_DB_ALIAS, help='Nominates a database to '
8                 'introspect.  Defaults to using the "default" database.'),
9+
10+        make_option('--skip', action='store_true', dest='skip',
11+            default=False, help='Skips tables that cannot be read instead of erroring out.'),
12     )
13 
14     requires_model_validation = False
15@@ -44,83 +47,92 @@ class Command(NoArgsCommand):
16         for table_name in connection.introspection.get_table_list(cursor):
17             yield 'class %s(models.Model):' % table2model(table_name)
18             try:
19-                relations = connection.introspection.get_relations(cursor, table_name)
20-            except NotImplementedError:
21-                relations = {}
22-            try:
23-                indexes = connection.introspection.get_indexes(cursor, table_name)
24-            except NotImplementedError:
25-                indexes = {}
26-            for i, row in enumerate(connection.introspection.get_table_description(cursor, table_name)):
27-                column_name = row[0]
28-                att_name = column_name.lower()
29-                comment_notes = [] # Holds Field notes, to be displayed in a Python comment.
30-                extra_params = {}  # Holds Field parameters such as 'db_column'.
31-
32-                # If the column name can't be used verbatim as a Python
33-                # attribute, set the "db_column" for this Field.
34-                if ' ' in att_name or '-' in att_name or keyword.iskeyword(att_name) or column_name != att_name:
35-                    extra_params['db_column'] = column_name
36-
37-                # Modify the field name to make it Python-compatible.
38-                if ' ' in att_name:
39-                    att_name = att_name.replace(' ', '_')
40-                    comment_notes.append('Field renamed to remove spaces.')
41-                if '-' in att_name:
42-                    att_name = att_name.replace('-', '_')
43-                    comment_notes.append('Field renamed to remove dashes.')
44-                if keyword.iskeyword(att_name):
45-                    att_name += '_field'
46-                    comment_notes.append('Field renamed because it was a Python reserved word.')
47-                if column_name != att_name:
48-                    comment_notes.append('Field name made lowercase.')
49-
50-                if i in relations:
51-                    rel_to = relations[i][1] == table_name and "'self'" or table2model(relations[i][1])
52-                    field_type = 'ForeignKey(%s' % rel_to
53-                    if att_name.endswith('_id'):
54-                        att_name = att_name[:-3]
55-                    else:
56+                try:
57+                    relations = connection.introspection.get_relations(cursor, table_name)
58+                except NotImplementedError:
59+                    relations = {}
60+                try:
61+                    indexes = connection.introspection.get_indexes(cursor, table_name)
62+                except NotImplementedError:
63+                    indexes = {}
64+                for i, row in enumerate(connection.introspection.get_table_description(cursor, table_name)):
65+                    column_name = row[0]
66+                    att_name = column_name.lower()
67+                    comment_notes = [] # Holds Field notes, to be displayed in a Python comment.
68+                    extra_params = {}  # Holds Field parameters such as 'db_column'.
69+
70+                    # If the column name can't be used verbatim as a Python
71+                    # attribute, set the "db_column" for this Field.
72+                    if ' ' in att_name or '-' in att_name or keyword.iskeyword(att_name) or column_name != att_name:
73                         extra_params['db_column'] = column_name
74+
75+                    # Modify the field name to make it Python-compatible.
76+                    if ' ' in att_name:
77+                        att_name = att_name.replace(' ', '_')
78+                        comment_notes.append('Field renamed to remove spaces.')
79+                    if '-' in att_name:
80+                        att_name = att_name.replace('-', '_')
81+                        comment_notes.append('Field renamed to remove dashes.')
82+                    if keyword.iskeyword(att_name):
83+                        att_name += '_field'
84+                        comment_notes.append('Field renamed because it was a Python reserved word.')
85+                    if column_name != att_name:
86+                        comment_notes.append('Field name made lowercase.')
87+
88+                    if i in relations:
89+                        rel_to = relations[i][1] == table_name and "'self'" or table2model(relations[i][1])
90+                        field_type = 'ForeignKey(%s' % rel_to
91+                        if att_name.endswith('_id'):
92+                            att_name = att_name[:-3]
93+                        else:
94+                            extra_params['db_column'] = column_name
95+                    else:
96+                        # Calling `get_field_type` to get the field type string and any
97+                        # additional paramters and notes.
98+                        field_type, field_params, field_notes = self.get_field_type(connection, table_name, row)
99+                        extra_params.update(field_params)
100+                        comment_notes.extend(field_notes)
101+
102+                        # Add primary_key and unique, if necessary.
103+                        if column_name in indexes:
104+                            if indexes[column_name]['primary_key']:
105+                                extra_params['primary_key'] = True
106+                            elif indexes[column_name]['unique']:
107+                                extra_params['unique'] = True
108+
109+                        field_type += '('
110+
111+                    # Don't output 'id = meta.AutoField(primary_key=True)', because
112+                    # that's assumed if it doesn't exist.
113+                    if att_name == 'id' and field_type == 'AutoField(' and extra_params == {'primary_key': True}:
114+                        continue
115+
116+                    # Add 'null' and 'blank', if the 'null_ok' flag was present in the
117+                    # table description.
118+                    if row[6]: # If it's NULL...
119+                        extra_params['blank'] = True
120+                        if not field_type in ('TextField(', 'CharField('):
121+                            extra_params['null'] = True
122+
123+                    field_desc = '%s = models.%s' % (att_name, field_type)
124+                    if extra_params:
125+                        if not field_desc.endswith('('):
126+                            field_desc += ', '
127+                        field_desc += ', '.join(['%s=%r' % (k, v) for k, v in extra_params.items()])
128+                    field_desc += ')'
129+                    if comment_notes:
130+                        field_desc += ' # ' + ' '.join(comment_notes)
131+                    yield '    %s' % field_desc
132+                for meta_line in self.get_meta(table_name):
133+                    yield meta_line
134+
135+            except:
136+                if options.get('skip'):
137+                    yield "    # Error reading this table"
138+                    yield "    pass"
139+                    yield
140                 else:
141-                    # Calling `get_field_type` to get the field type string and any
142-                    # additional paramters and notes.
143-                    field_type, field_params, field_notes = self.get_field_type(connection, table_name, row)
144-                    extra_params.update(field_params)
145-                    comment_notes.extend(field_notes)
146-
147-                    # Add primary_key and unique, if necessary.
148-                    if column_name in indexes:
149-                        if indexes[column_name]['primary_key']:
150-                            extra_params['primary_key'] = True
151-                        elif indexes[column_name]['unique']:
152-                            extra_params['unique'] = True
153-
154-                    field_type += '('
155-
156-                # Don't output 'id = meta.AutoField(primary_key=True)', because
157-                # that's assumed if it doesn't exist.
158-                if att_name == 'id' and field_type == 'AutoField(' and extra_params == {'primary_key': True}:
159-                    continue
160-
161-                # Add 'null' and 'blank', if the 'null_ok' flag was present in the
162-                # table description.
163-                if row[6]: # If it's NULL...
164-                    extra_params['blank'] = True
165-                    if not field_type in ('TextField(', 'CharField('):
166-                        extra_params['null'] = True
167-
168-                field_desc = '%s = models.%s' % (att_name, field_type)
169-                if extra_params:
170-                    if not field_desc.endswith('('):
171-                        field_desc += ', '
172-                    field_desc += ', '.join(['%s=%r' % (k, v) for k, v in extra_params.items()])
173-                field_desc += ')'
174-                if comment_notes:
175-                    field_desc += ' # ' + ' '.join(comment_notes)
176-                yield '    %s' % field_desc
177-            for meta_line in self.get_meta(table_name):
178-                yield meta_line
179+                    raise
180 
181     def get_field_type(self, connection, table_name, row):
182         """