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?
1 Answer
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
6 Comments
? and =, it should be escaped first? In this sense, maybe checking os.path.exists() is better?? 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.? 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.os.path.exists() or uri? 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.
os.path.exists()to check the file first