Search code examples
pythonsqlitepython-daemon

Python daemon can see database, but complains that tables do not exist


I have a vanilla python that connects to a sqlite database.

Everything works fine until I try to run it as a daemon. Here is the code I'm using to do that:

def start(self):
  if self.lockfile.is_locked():
    exit_with_code(7, self.pid_file)

  # If we're running in debug, run in the foreground, else daemonise
  if self.options['debug']:
    try:
      self.main()
    except KeyboardInterrupt:
      pass
    finally:
      self.close_gracefully()
  else:
    context = daemon.DaemonContext(
      files_preserve = [self.logger.socket(), self.lockfile]
    )

    context.signal_map = {
      signal.SIGTERM: self.close_gracefully
    }

    with context: self.main()

I can run it in the foreground with python -m starter -debug and everything is fine, my app writes into the database, but when I leave the debug flag off I see the following when I try to write:

no such table: Frontends

I know that the frontends table exists because I've opened the database up. I assume that python is finding the database, because there would be an entirely different error message otherwise.

All my files are owned by vagrant, and ls -l shows the following:

-rwxrwxrwx 1 vagrant vagrant 9216 Nov  9 18:09 development.sqlite

Anyone got any tips?

Update

As requested, here is the code for my db

import os
import sqlite3

class Database(object):

    def __init__(self, db_file='/vagrant/my_daemon/db/development.sqlite'):

        self.db = sqlite3.connect(db_file)

        if os.path.exists(db_file):
            print "db exists"

And when I run this it prints "db exists". I instantiate the database in starter.py with a call to Database().


Solution

  • Python daemon closes all open file descriptors (except stdin, stout and stderr) when you daemonise.

    I spent ages trying to figure out which files to keep open to prevent my database from being inaccessible, and in the end I found that it's easier to initialise the database inside the daemon context rather than outside. That way I don't need to worry about which files should stay open.

    Now everything is working fine.