Django. SQLite database restore on project restart

I have an IoT Django project. It has a configuration and operational subsystems. Basically, the project receives events from many devices and stores them in the database. The configuration of devices properties are applied by Django Admin. So after the configuration changes I need to restart the project. Everything works well but the restart of my server causes sometimes quite a long delay during the next project start (1-5 minutes). It looks like it recovers the SQLite database. After this period it works normally.
For the supervising, I use an external program which sends a REST API message to close the project gracefully. Actually, the content of this function is as follows:

from django.db import connection
connection.close()
os._exit(1)

I used the default SQLite configuration and tried to set the WAL-mode of it. The only difference is the WAL-mode generates a huge file ~1GB. The code of the “WAL-mode” is here:

class CoreConfig(AppConfig):
    """Core application config."""

    name = "core"

    def ready(self) -> None:
        def enable_sqlite_pragmas(sender: t.Any, connection: t.Any, **kwargs: t.Any) -> None:
            """Enable the necessary sqlite pragmas."""
            cursor = connection.cursor()
            cursor.execute("PRAGMA journal_mode = WAL;")
            cursor.execute("PRAGMA synchronous = NORMAL;")
            cursor.execute("PRAGMA wal_checkpoint(TRUNCATE);")
        
        connection_created.connect(enable_sqlite_pragmas)

I know that SQLite is not a production database and some of you would suggest using MySQL or PostgreSQL. Unfortunately, it’s almost impossible because the project is installed on the customer’s computer and maintenance of a production database is quite complicated because we have tens of customers.

So my question is how to deal with such an issue. Or maybe someone suggests other approaches to close the Django/SQLite database gracefully.

Thanks in advance.

It sounds like your project may be in the middle of some updates when you’re restarting it.

How are you running your project?

How are you performing the restarts?
Are you waiting for existing transactions to complete before doing that?

In general, you don’t want to shut down your project from within the project itself. You should be controlling it externally, allowing it to perform its own clean-up.

How are you running your project?
I use PyInstaller with a starting script having this code:
I use django-channels/daphne asgi server. I have a script to use SSL (https):

        sys.argv = ['daphne', '-essl:port=%d:interface=%s:privateKey=key.pem:certKey=cert.pem' % (
            json_settings['SERVER_PORT'], '0.0.0.0'), '--websocket_timeout=-1',
                    'TheProject.asgi:application']
        from daphne.cli import CommandLineInterface

        CommandLineInterface.entrypoint()

and supervising program runs this “project.exe” (I run under Windows 10).

How are you performing the restarts?
The supervising program sends REST API (HTTP) request and it runs the code cited in my first message. So the project calls sys._exit(0)

Are you waiting for existing transactions to complete before doing that?
No, It is probably a good idea. How to do this? Since I have several threads which can perform some database operations. Do I need to track every “actor” to wait until they finish work?

What you probably want to do is send the sigint signal to the Daphne process. (It’s what a “ctrl-C” does) That would be the appropriate way to cause Daphne to shutdown.

Again, you want to control this from outside your project. It’s an important perspective to keep in mind that your Django code does not (and should not) control the process in which it is being run.

Do you think sending the sigint signal to the Daphne would tell Daphne to close connection gracefully?

It’s supposed to - what you’re doing is sending the same signal that a ctrl-c from the keyboard does, and that’s the “close cleanly” signal. I’m also seeing references in Twisted-related docs that sigterm is appropriate.

One of the two should do it for you.

Actually, on Windows, I’m not sure how that works… What I’m finding in a brief search all recommends setting up the twisted process as a service, and using the standard windows facilities for starting and stopping the service. That should also provide a clean interface.

Thank you for your valuable advice. I’ll try.