diff --git a/django/core/db/backends/sqlite3.py b/django/core/db/backends/sqlite3.py index 9133d08bba..1a4a80d632 100644 --- a/django/core/db/backends/sqlite3.py +++ b/django/core/db/backends/sqlite3.py @@ -185,4 +185,36 @@ DATA_TYPES = { 'USStateField': 'varchar(2)', } -DATA_TYPES_REVERSE = {} +# Maps SQL types to Django Field types. Some of the SQL types have multiple +# entries here because SQLite allows for anything and doesn't normalize the +# field type; it uses whatever was given. +BASE_DATA_TYPES_REVERSE = { + 'bool': 'BooleanField', + 'boolean': 'BooleanField', + 'smallint': 'SmallIntegerField', + 'smallinteger': 'SmallIntegerField', + 'int': 'IntegerField', + 'integer': 'IntegerField', + 'text': 'TextField', + 'char': 'CharField', + 'date': 'DateField', + 'datetime': 'DateTimeField', + 'time': 'TimeField', +} + +# This light wrapper "fakes" a dictionary interface, because some SQLite data +# types include variables in them -- e.g. "varchar(30)" -- and can't be matched +# as a simple dictionary lookup. +class FlexibleFieldLookupDict: + def __getitem__(self, key): + key = key.lower() + try: + return BASE_DATA_TYPES_REVERSE[key] + except KeyError: + import re + m = re.search(r'^\s*(?:var)?char\s*\(\s*(\d+)\s*\)\s*$', key) + if m: + return ('CharField', {'maxlength': m.group(1)}) + raise KeyError + +DATA_TYPES_REVERSE = FlexibleFieldLookupDict() diff --git a/django/core/management.py b/django/core/management.py index d14c97b568..d41392d93c 100644 --- a/django/core/management.py +++ b/django/core/management.py @@ -591,9 +591,19 @@ def inspectdb(db_name): field_type_was_guessed = True else: field_type_was_guessed = False + + # This is a hook for DATA_TYPES_REVERSE to return a tuple of + # (field_type, extra_params_dict). + if type(field_type) is tuple: + field_type, extra_params = field_type + else: + extra_params = {} + + if field_type == 'CharField' and row[3]: + extra_params['maxlength'] = row[3] + field_desc = '%s = meta.%s(' % (column_name, field_type) - if field_type == 'CharField': - field_desc += 'maxlength=%s' % (row[3]) + field_desc += ', '.join(['%s=%s' % (k, v) for k, v in extra_params.items()]) field_desc += ')' if field_type_was_guessed: field_desc += ' # This is a guess!' diff --git a/docs/django-admin.txt b/docs/django-admin.txt index 79cf4521ca..3f024b9f7f 100644 --- a/docs/django-admin.txt +++ b/docs/django-admin.txt @@ -87,8 +87,7 @@ customizations. In particular, you'll need to do this: doesn't yet introspect primary keys. ``inspectdb`` works with PostgreSQL, MySQL and SQLite. Foreign-key detection -only works in PostgreSQL. In SQLite, it cannot detect column types; it'll -use ``TextField`` for each column. +only works in PostgreSQL. install [modelmodule modelmodule ...] -------------------------------------