9

sqlite3.connect() will create the db file if it does not exist. I'd like it to fail. Is there a way to do so?

2
  • you can use os.path.exists() to check the file first Commented Sep 6, 2019 at 20:37
  • I could. But I'd expect an option to make it easier. Commented Sep 6, 2019 at 20:42

1 Answer 1

9

The first way is to check the file path with os.path.isfile :

import sqlite3
import os

my_path = 'database.db' # or 'absolute_path/to/the/file'
if os.path.isfile(my_path):
    sqlite3.connect(my_path)

Otherwise you can use the uri=True parameter to specify an opening mode and raise an error in case the file is missing. Without the mode, the file will be created if not exists, so you can use for example rw or ro to avoid the new file :

  • to open with read & write mode :

    sqlite3.connect('file:database.db?mode=rw', uri=True)
    
  • to open in read only mode :

    sqlite3.connect('file:database.db?mode=ro', uri=True)
    

This will raise the following error if the file doesn't exists :

sqlite3.OperationalError: unable to open database file

You can find more about these modes in these chapters of the doc :

https://www.sqlite.org/uri.html

https://www.sqlite.org/c3ref/open.html#urifilenamesinsqlite3open


To be able to open files with special characters (special for an URI), another way is to use the following method :

import pathlib

my_db = pathlib.Path('path/to/data?ba=se.db').as_uri()
sqlite3.connect('{}?mode=rw'.format(my_db), uri=True)

# or sqlite3.connect(f'{my_db}?mode=rw', uri=True)  with f-string
Sign up to request clarification or add additional context in comments.

6 Comments

This is a little combersome. If the database file name contains ? and =, it should be escaped first? In this sense, maybe checking os.path.exists() is better?
adding ? or = in a filename proves a real passion of risks :) Eventually this can be handled with the feature added in python 3.7 docs.python.org/3/library/sqlite3.html#sqlite3.connect : Changed in version 3.7: database can now also be a path-like object, not only a string.
It is not that I want to use ? and = in filenames. But I need to code to guard against such cases if I use the uri option. Not sure path-like object solves the problem. If it is used, I don't see a way to specify read-only.
indeed, i was thinking that creating a path-like object could fail if the path doesn't exist, but i can't find a way either. Not sure you can find other solutions than os.path.exists() or uri
@user1424739 At least the answer provides a solution to your question. You can always perform prior file/path validation to exclude files that would contain ? and =. This would require a very simple regex check that excludes certain character and/or suffixes on the filename. Being security minded is good, but I still wonder if this level of concern is necessary since if some rogue process had crafted and created a filename that could spoof the URI format, then it's likely that that process has already compromised the system beyond tricking your app into opening a newly-created db file.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.