pythonsqlitepython-daemon

Python - Table not found error when using SQlite3 with Daemonize


I have a slack bot that accesses an SQlite database. When I run the bot in the foreground, everything works but when I run it as a daemon, it seems to connect to my database but then returns "table not found" on every query that I run.

The thing is, this used to work until my latest version and I can't find what changed, so I made a stripped down version as a test but I still have the same problem. See below:

import syslog
import sqlite3
import os
from daemonize import Daemonize
from slackclient import SlackClient
from qatoken import token

#Slack vars
nickname = "NetBot-QA"
dump = "#net-dump-qa"
channel = "#net-alerts-qa"
avatar = ":loader:"

#Daemonize vars
pid = "/tmp/netbot-qa.pid"
app = "net-bot-qa"
syslog.openlog('netbot', 0, syslog.LOG_LOCAL4 )

###################################################### MAIN
def main():

    sc = SlackClient(token)
    sc.api_call("chat.postMessage", username=nickname, channel=dump, text="{0}/net-alerts-test.db".format(os.path.dirname(__file__)), icon_emoji=avatar)

    try:
        conn = sqlite3.connect("{0}/net-alerts-test.db".format(os.path.dirname(__file__)))
        c = conn.cursor()
        c.execute("SELECT * from maint_calendar")
        sc.api_call("chat.postMessage", username=nickname, channel=dump, text="made it!", icon_emoji=avatar)
    except (SystemExit, KeyboardInterrupt):
        raise
    except Exception, e:
        sc.api_call("chat.postMessage", username=nickname, channel=dump, text="The bot crashed", icon_emoji=avatar)
        syslog.syslog("error: {0}".format(e))

########################################################################################
#main()
########################################################################################
#main()
daemon = Daemonize(app=app, pid=pid, action=main)
daemon.start()    

If I run main(), I get the slack message "Made it!", but if I comment it out and run daemon.start() instead, I get "The bot crashed".

When I cat /var/log/messages, this is what I see:

Nov 16 09:47:37 server1 netbot: error: no such table: maint_calendar

[root@server1 net-alerts]# pwd
/opt/bots/net-alerts

[root@server1 net-alerts]# sqlite3 net-alerts-test.db
SQLite version 3.7.17 2013-05-20 00:56:22
sqlite> .schema
CREATE TABLE maint_calendar (start time, finish time, summary text, dc_tag text, provider text, CONSTRAINT start_sum PRIMARY KEY (start, summary));

I've also tried running this with a static path to the db but os.path.dirname has worked very well with every other script I use. I found another post saying you have to make the DB connection inside the Daemon context (main()) but I've been doing this from the start. I'm running out of ideas.


Solution

  • It seems to me, that this line:

    conn = sqlite3.connect("{0}/net-alerts-test.db".format(os.path.dirname(__file__)))
    

    Is actually connecting to two different sources, depending if you daemonize or just run main().

    Just save the file to db in a global variable, which you use later. E.g.:

    DB_PATH = "{0}/net-alerts-test.db".format(os.path.dirname(__file__))
    ...
    def main():
    
        sc = SlackClient(token)
        sc.api_call("chat.postMessage", username=nickname, channel=dump, text="{0}/net-alerts-test.db".format(os.path.dirname(__file__)), icon_emoji=avatar)
    
        try:
            conn = sqlite3.connect(DB_PATH)