Unable to mesh an existing DB together with Django

I have an existing DB on MSSQL. I imported it into Django using manage.py inspectdb > manage.py

I ran makemigrations and migrate.

This is an example of one of the models:

class Clerk(models.Model):
    clientid = models.AutoField(db_column='clientId', primary_key=True)
    clerkname = models.CharField(db_column='clerkName', max_length=30, default="ClerkNameDefault")
    ...

    class Meta:
        managed = False
        db_table = 'Clerks'

So far, so good!

However, when I try to make an instance, it looks like I am encountering problems with the clientid.

>>> from webapi.models import Clerk
>>> clerk = Clerk(clerkname="hi")
>>> clerk.clientid

Strange! No clientid, despite it being set as an AutoField. Could it be that it’s because Managed = False? Well, let’s set the id myself and see where this goes:

>>> clerk.clientid=1
>>> clerk.save()
Traceback (most recent call last):
  File "C:\git\django-mssql\venv\lib\site-packages\django\db\backends\utils.py", line 85, in _execute
    return self.cursor.execute(sql, params)
  File "C:\git\django-mssql\venv\lib\site-packages\mssql\base.py", line 576, in execute
    return self.cursor.execute(sql, params)
pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Table 'Clerks' does not have the identity property. Cannot perform SET operation. (8106) (SQLExecDirectW)")

Any hints? I hope I provided enough context.

For clarity, what I wanted was for Django to automatically populate the clientid portion, and for save() to write the model into my database.

Edit: 8 hours later, I have no idea if I did the right thing or not, but I went into my table > right click: “Design” > clientId > column properties: Identity Specification: (is identity) and clicked yes there.

I wonder if I need to manually do this for the rest of my tables…

Hi,

The behavior you’re describing is how Django works when it comes to AutoField: Model instance reference | Django documentation | Django

The value for clientid will be None for a new model until you call save() for the first time. When you call save(), Django will receive the automatically generated value from the database and update the python object.
Try the following:

>>> clerk = Clerk(clerkname="hi")
>>> clerk.clientid is None  # should be True
>>> clerk.save()
>>> clerk.clientid is None  # should now be False

Hello. Thanks a lot for pointing me to the documentation. My apologies for totally missing that point.

The takeaway for this situation was that the DB needs to have something known as “identity”–still fuzzy on that that does, but it might be out of the scope of Django. :slight_smile: Appreciate it.