Search code examples
pythonsqlitepermissionstelethon

Python/Telethon on SQLite database operational error: unable to open database file


I have a python/telethon Telegram bot project consisting of a single python file, an SQLite databse, and a config file. The bot runs fine on my local system in a virtual environment (all three files are in the same directory) but when I attempt to run the python file on ubuntu server, I'm running into the following error.

Project files are in /usr/local/bin/project/:

Traceback (most recent call last):
  File "/usr/local/bin/project/script.py", line 19, in <module>
    client = TelegramClient(session_name, API_ID, API_HASH).start(bot_token=BOT_TOKEN)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/telethon/client/telegrambaseclient.py", line 289, in __init__
    session = SQLiteSession(session)
              ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/telethon/sessions/sqlite.py", line 47, in __init__
    c = self._cursor()
        ^^^^^^^^^^^^^^
  File "/usr/local/lib/python3.11/dist-packages/telethon/sessions/sqlite.py", line 242, in _cursor
    self._conn = sqlite3.connect(self.filename,
                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
sqlite3.OperationalError: unable to open database file

Below are the contents of script.py:

import configparser
import re
from telethon import TelegramClient, Button, events
import sqlite3
from datetime import datetime
import traceback

print("Initializing configurations...")
config = configparser.ConfigParser()
config.read('config.ini', encoding='utf-8')

API_ID = config.get('default','api_id') 
API_HASH = config.get('default','api_hash')
BOT_TOKEN = config.get('default','bot_token')
session_name = "sessions/Bot"

# Start the bot session
client = TelegramClient(session_name, API_ID, API_HASH).start(bot_token=BOT_TOKEN)

@client.on(events.NewMessage(pattern="(?i)/start"))
async def start(event):
    
    sender = await event.get_sender()
    SENDER = str(sender.id)
    
    await event.reply('Hello!.')
    
##### MAIN
if __name__ == '__main__':
    try:
        print("Initializing Database...")
        # Connect to local database
        db_name = 'database.db'
        conn = sqlite3.connect(db_name, check_same_thread=False)
        # Create the cursor
        crsr = conn.cursor() 
        print("Connected to the database")

        # Command that creates the "customers" table 
        sql_command = """CREATE TABLE IF NOT EXISTS customers ( 
            id INTEGER PRIMARY KEY AUTOINCREMENT, 
            lname VARCHAR(200),
            fname VARCHAR(200), 
            note VARCHAR(200));"""
        crsr.execute(sql_command)
        print("All tables are ready")

        print("Bot Started")
        client.run_until_disconnected()

    except Exception as error:
        print('Cause: {}'.format(error))

These are the contents of config.ini:

; DO NOT MODIFY THE LINE BELOW!!! ([default])
[default]


; EDITABLE FIELDS:
api_id = 000000
api_hash = 000000000000000000
bot_token = 00000000000000000000000000

I checked permissions on all three files, and am getting the following:

-rw-r--rw- 1 root root 10601 Mar  4 00:52 script.py

-rw-rw-rw- 1 root root 716800 Mar  4 00:52 database.db

-rw-r--rw- 1 root root 195 Mar  4 00:52 config.ini

Solution

  • TelegramClient by default tries to create a sqlite file for stroing the session information.

    The first parameter you pass to the constructor of the TelegramClient is the session, and defaults to be the session name (or full path). https://docs.telethon.dev/en/stable/concepts/sessions.html

    since you have named your session "sessions/Bot", it tries to find a folder named "sessions" and then create a db file named "Bot". But it can't find the folder.

    To fix this error, you can either change your session_name to just a filename like "Bot". Or you can also just create an empty folder name sessions and it should work well.

    Hope this helps!