【发布时间】:2020-01-09 16:51:06
【问题描述】:
sqlite3.connect() 如果 db 文件不存在,将创建它。我希望它失败。有办法吗?
【问题讨论】:
-
可以先使用
os.path.exists()查看文件 -
我可以。但我希望有一个选项可以让它变得更容易。
标签: python python-3.x sqlite
sqlite3.connect() 如果 db 文件不存在,将创建它。我希望它失败。有办法吗?
【问题讨论】:
os.path.exists()查看文件
标签: python python-3.x sqlite
第一种方法是用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)
否则,您可以使用uri=True 参数指定打开mode 并在文件丢失的情况下引发错误。
如果没有mode,文件将在不存在时创建,因此您可以使用例如rw 或ro 来避免新文件:
以读写模式打开:
sqlite3.connect('file:database.db?mode=rw', uri=True)
以只读模式打开:
sqlite3.connect('file:database.db?mode=ro', uri=True)
如果文件不存在,这将引发以下错误:
sqlite3.OperationalError: 无法打开数据库文件
您可以在文档的这些章节中找到有关这些模式的更多信息:
https://www.sqlite.org/uri.html
https://www.sqlite.org/c3ref/open.html#urifilenamesinsqlite3open
为了能够打开带有特殊字符(URI 专用)的文件,另一种方法是使用以下方法:
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
【讨论】:
?和=,应该先转义?从这个意义上说,也许检查os.path.exists() 更好?
? 或 = 证明了真正的风险热情 :) 最终这可以通过 python 3.7 docs.python.org/3/library/sqlite3.html#sqlite3.connect 中添加的功能来处理:在 3.7 版中更改: 数据库现在也可以是一个类似路径的对象,而不仅仅是一个字符串。
? 和=。但是如果我使用uri 选项,我需要编写代码来防止这种情况。不确定类似路径的对象能否解决问题。如果使用它,我看不到指定只读的方法。
os.path.exists() 或 uri 之外的其他解决方案
? 和= 的文件。这将需要一个非常简单的正则表达式检查,排除文件名上的某些字符和/或后缀。有安全意识是好的,但我仍然想知道这种程度的关注是否是必要的,因为如果某些流氓进程制作并创建了一个可以欺骗 URI 格式的文件名,那么很可能该进程已经损害了系统,而不仅仅是欺骗你的应用程序打开一个新创建的数据库文件。