python manage.py inspectdb makes all fields with a default value blank=True, null=True

52 views
Skip to first unread message

Kimball Leavitt

unread,
Jul 20, 2018, 2:37:17 PM7/20/18
to Django users
I'm not sure if this is a bug, feature request, or something else, so I thought I'd start here.

Summary: python manage.py inspectdb makes all fields with a default value blank=True, null=True

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
  • 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:

# 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


# 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.

Am I missing something?

Jason

unread,
Jul 20, 2018, 3:06:45 PM7/20/18
to Django users
Nice edge case you found.  I would suggest raising this to the django-developers to get core framework dev attention or make a bug report on the tracker.

Kimball Leavitt

unread,
Jul 20, 2018, 4:10:57 PM7/20/18
to Django users
Will do. Thanks.

Tim Graham

unread,
Jul 20, 2018, 6:54:17 PM7/20/18
to Django users

For future reference, creating a bug report is sufficient. No need to post to django-developers.


I'll post my analysis from the ticket below.

https://code.djangoproject.com/ticket/29583#comment:1


I think you made a mistake in your analysis. In the FieldInfo initialization, line[6] (not info.column_default) corresponds to row[6] in inspectdb. 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."

Kimball Leavitt

unread,
Jul 21, 2018, 12:30:25 AM7/21/18
to django...@googlegroups.com

Good to know, I’ll keep that in mind.

 

Yes, I was mistaken. And I guess I missed that line in the docs. Thanks!

--
You received this message because you are subscribed to a topic in the Google Groups "Django users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/django-users/-ZJ3Fwt6JIs/unsubscribe.
To unsubscribe from this group and all its topics, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/a189a49b-b9b6-4d00-adaa-42e94eb70e74%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

 

Reply all
Reply to author
Forward
0 new messages