jazzband / django-simple-history

Store model history and view/revert changes from admin site.
https://django-simple-history.readthedocs.org
BSD 3-Clause "New" or "Revised" License
2.22k stars 481 forks source link

Running populate_history command fails with mssql-django #1417

Open paxw-panevo opened 3 weeks ago

paxw-panevo commented 3 weeks ago

Describe the bug When we run the command python manage.py populate_history --auto --batchsize 500, we get an error:

Related:

To Reproduce Steps to reproduce the behavior:

  1. Use MS SQL.
    • We are using the docker image mcr.microsoft.com/mssql/server:2017-latest
    • In django's DATABASES settings, under OPTIONS, we pass TrustServerCertificate=yes;MARS Connection=True for extra_params [^1]
  2. Have a model with instances that exceeds the batch_size you will pass in step 5 [*]
  3. Follow setup instructions of django-simple-history (install package, setup middleware, etc.) up to running the populate_history command
  4. Run the populate_history command.

[*] The point is to reproduce the scenario where the iterator (server-side db cursor) is not done returning rows to Django. If you set --batch_size to 1 and you have a model that has more than 1 instance, you should also experience the same error.

[^1] Our django databases settings would look something like,

"default": {
            "ENGINE": "mssql",
            "NAME": DB_NAME,
            "USER": DB_USER,
            "PASSWORD": DB_PWD,
            "HOST": DB_SERVER,
            "PORT": DB_PORT,
            "OPTIONS": {
                "driver": "ODBC Driver 18 for SQL Server",
                "return_rows_bulk_insert": False,
                "extra_params": "TrustServerCertificate=yes;MARS_Connection=yes",
            },

Actual behavior

We get an error message: django.db.utils.ProgrammingError: ('42000', '[42000] [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]New transaction is not allowed because there are other threads running in the session. (3988) (SQLSetConnectAttr)')

In every run of populate_history, the logs just before the error is raised shows:

Expected behavior Running populate_history is successful.

Screenshots This is the stack trace, image

Environment (please complete the following information):