`sqldiff` reports incorrect varchar length differences for PostgreSQL fields

Author: paradox-lab2Created Mar 18, 2026Updated Mar 18, 2026

Description

The sqldiff command is incorrectly reporting field length differences between the model and database for CharField fields with max_length defined, even when the database schema is correctly set to the expected length.

Environment

  • Django: 5.1.13
  • django-extensions: 4.1
  • Database: PostgreSQL 17.2
  • Python: 3.12

Steps to Reproduce

  1. Create a model with CharField that has max_length specified:
python
class Snippet(models.Model):
    title = models.CharField(max_length=100, blank=True, default='')
    code = models.TextField()
    linenos = models.BooleanField(default=False)
    language = models.CharField(
        choices=LANGUAGE_CHOICES, default='python', max_length=100)
    style = models.CharField(
        choices=STYLE_CHOICES, default='friendly', max_length=100)
    owner = models.ForeignKey(
        'users.User', related_name='snippets', on_delete=models.CASCADE)
    highlighted = models.TextField()
  1. Apply migrations to create the table in PostgreSQL
  2. Run python manage.py sqldiff app_name -t

Actual Behavior

sqldiff reports:

+ Application: snippets
|-+ Differences for model: Snippet
|--+ field 'title' parameters differ: db='varchar', model='varchar(100)'
|--+ field 'language' parameters differ: db='varchar', model='varchar(100)'
|--+ field 'style' parameters differ: db='varchar', model='varchar(100)'

Additional Information

  • Verified the database schema is correct using \d table_name in psql, which shows character varying(100) for all three fields
  • Confirmed that the actual database columns have the correct length constraint
  • Issue appears to be in how sqldiff queries the database schema

The database schema is correct but sqldiff is not properly detecting the length of the varchar fields in PostgreSQL.

app=# \d snippets_snippet
                                Table "public.snippets_snippet"
   Column    |          Type          | Collation | Nullable |             Default
-------------+------------------------+-----------+----------+----------------------------------
 id          | bigint                 |           | not null | generated by default as identity
 title       | character varying(100) |           | not null |
 code        | text                   |           | not null |
 linenos     | boolean                |           | not null |
 language    | character varying(100) |           | not null |
 style       | character varying(100) |           | not null |
 highlighted | text                   |           | not null |
 owner_id    | bigint                 |           | not null |
Indexes:
    "snippets_snippet_pkey" PRIMARY KEY, btree (id)
    "snippets_snippet_owner_id_20604299" btree (owner_id)
Foreign-key constraints:
    "snippets_snippet_owner_id_20604299_fk_users_user_id" FOREIGN KEY (owner_id) REFERENCES users_user(id) DEFERRABLE INITIALLY DEFERRED

Source: django-extensions/django-extensions