Opened 6 years ago
Closed 6 years ago
#29583 closed Bug (invalid)
python manage.py inspectdb makes all fields with a default value blank=True, null=True
Reported by: | Kimball Leavitt | Owned by: | nobody |
---|---|---|---|
Component: | Core (Management commands) | Version: | 2.0 |
Severity: | Normal | Keywords: | manage.py, inspectdb, models |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | yes | UI/UX: | no |
Description
Wasn't sure on the category or difficulty of fix, so logged it as an "easy pickings bug".
I'm using:
Ubuntu 16.04
Python 3.7.0
Django 2.0.4
Mariadb 10.2.16
Before I get into this, I realize that
-"Django is best suited for developing new applications"
-This probably isn't a huge deal or a high priority
...BUT I figured I'd submit this anyway while I was thinking about it. Maybe it'll save someone some extra work down the line.
Steps to reproduce:
- Setup a legacy db in settings.py (see https://docs.djangoproject.com/en/2.0/howto/legacy-databases/)
-Prerequisite: you have a column in one of your tables that has a default value.
-Example: test_field int(11) DEFAULT 1
- Run python manage.py inspectdb [--database DATABASE_NAME [ TABLE ] ] > models.py (or don't include "> models.py" and you can view the results from the command line)
- Open models.py
-test_field will look something like this:
test_field = models.IntegerField(blank=True, null=True)
-What I would expect:
test_field = models.IntegerField(default=1)
What I've been able to dig up:
# https://www.google.com/url?q=https%3A%2F%2Fgithub.com%2Fdjango%2Fdjango%2Fblob%2Fmaster%2Fdjango%2Fcore%2Fmanagement%2Fcommands%2Finspectdb.py%23L144&sa=D&sntz=1&usg=AFQjCNGZLkFkaqIJ1Ap1dhXRB0jARXcCoA
# from inspectdb.py (line 144, comments included in the original file, )
142 # Add 'null' and 'blank', if the 'null_ok' flag was present in the 143 # table description. 144 if row[6]: # If it's NULL... 145 extra_params['blank'] = True 146 extra_params['null'] = True
# https://github.com/django/django/blob/master/django/db/backends/mysql/introspection.py#L95+info.column_default
# from introspection.py in get_field_description (line 95, comment is mine)
86 fields = [] 87 for line in cursor.description: 88 info = field_info[line[0]] 89 fields.append(FieldInfo( 90 *line[:3], 91 to_int(info.max_len) or line[3], 92 to_int(info.num_prec) or line[4], 93 to_int(info.num_scale) or line[5], 94 line[6], 95 info.column_default, # THIS LINE IS JUST WHATEVER THE COLUMN DEFAULT IS 96 info.extra, 97 info.is_unsigned, 98 )) 99 return fields
I'm sure there are a lot of things I don't understand about this, but I don't think that having a default value should automatically add blank=True, null=True.
Is having a default value really a "'null_ok' flag"?
I think it should only put blank=True, null=True if the default is set to NULL in the column. Otherwise, it should set the default to whatever the default value is (ex: default=1)
Caveat: I've only tested this with int fields.
I think you made a mistake in your analysis. In the
FieldInfo
initialization,line[6]
(notinfo.column_default
) corresponds torow[6]
ininspectdb
. In your example,test_field int(11) DEFAULT 1
seems to be nullable (according to the MySQL documentation, "If neither NULL nor NOT NULL is specified, the column is treated as though NULL had been specified." -- I guess it's the same for MariaDB.As the documentation says, "database defaults aren’t translated to model field defaults or detected in any fashion by inspectdb."