有关配置SQLite数据库的URI路径的困惑

时间:2019-06-02 15:30:21

标签: python sqlite uri relative-path absolute-path

嗨,我正在使用Flask和Sqlite3构建Web应用程序。我在连接数据库时遇到了一段时间的问题,当我写这篇文章时它不起作用:

#version 1
app.config['SQLALCHEMY_DATABASE_URI'] =
'sqlite:////C:/Users/Giang/PyCharmProjects/FlaskWebBlog/FlaskWebBlog/site.db'

Python给了我操作上的错误:无法打开数据库,因为我在冒号后写了4个斜杠。在阅读了sqlalchemy文档并进行了许多试验之后,我发现这是可行的:

#with 3 slashes, version 2
app.config['SQLALCHEMY_DATABASE_URI'] = 

 'sqlite:///C:/Users/Giang/PyCharmProjects/FlaskWebBlog/FlaskWebBlog/site.db'

或带有4个斜杠但不带C的

#version 3
app.config['SQLALCHEMY_DATABASE_URI'] = 

'sqlite:////Users/Giang/PyCharmProjects/FlaskWebBlog/FlaskWebBlog/site.db'

我很困惑,因为基于连接字符串的文档:SQLite数据库的文件规范被视为URL的“数据库”部分。请注意,SQLAlchemy网址的格式为:

driver://user:pass@host/database

这意味着要使用的实际文件名以第三个斜杠右边的字符开头。因此,连接到相对文件路径如下所示:

# relative path
e = create_engine('sqlite:///path/to/database.db')

以斜杠开头的绝对路径表示您需要四个斜杠:

# absolute path
e = create_engine('sqlite:////path/to/database.db')
因此,如果我使用绝对路径,我需要4个斜杠,但是当我使用版本1时,python给了我错误。当我在版本2中使用3个斜杠作为绝对路径时,它起作用了。

所以我真的很困惑。谁能为我解释为什么?我真的很感激。谢谢

2 个答案:

答案 0 :(得分:2)

如果您将 SQLite3 指向当前工作目录以外的位置,我建议您执行以下操作以避免找不到数据库的问题:

import os
study_and_database_name = "something_unique"
rdb_string_url = "sqlite:///" + os.path.join(dir, (study_and_database_name + ".db"))
rdb_raw_bytes_url = r'{}'.format(rdb_string_url)

恢复存储在 RDB study 中的 Optuna storage 时对我有用:

storage_instance = optuna.storages.RDBStorage(url=rdb_raw_bytes_url)
study_instance = optuna.create_study(
    study_name=study_and_database_name,
    storage=storage_instance,
    load_if_exists=True,
)

答案 1 :(得分:1)

关于database组件被读为第三个斜杠后的所有字符,您是正确的。这是解析后的:版本1 URL

>>> import sqlalchemy.engine.url as url
>>> url.make_url('sqlite:////C:/Users/Giang/PyCharmProjects/FlaskWebBlog/FlaskWebBlog/site.db')
sqlite:////C:/Users/Giang/PyCharmProjects/FlaskWebBlog/FlaskWebBlog/site.db

>>> vars(_)
{'drivername': 'sqlite',
 'username': None,
 'password_original': None,
 'host': None,
 'port': None,
 'database': '/C:/Users/Giang/PyCharmProjects/FlaskWebBlog/FlaskWebBlog/site.db',
 'query': {}}

在Windows中,指向“当前工作目录的根驱动器”的路径gets normalized开头的斜杠。使用pywin32,我们可以调用GetFullPathName来查看路径的规范化版本:

>>> import os
>>> import win32file

>>> os.getcwd()
'C:\\Users\\they4kman'

>>> win32file.GetFullPathName('/C:/test')
'C:\\C:\\test'

>>> win32file.GetFullPathName('/test')
'C:\\test'

>>> win32file.GetFullPathName('C:/test')
'C:\\test'

版本1不起作用的原因是,同时指定前导斜杠和驱动器号将被Windows规范化为无效路径。 (更具体地说,该路径无效,因为Windows路径中不允许使用冒号,除非在开始时作为驱动器说明符。)

要显示如何根据环境对前斜杠进行标准化,让我们将当前工作目录更改为另一个驱动器上的目录,并检查标准化路径:

>>> os.chdir('D:/')
>>> os.getcwd()
'D:\\'

>>> win32file.GetFullPathName('/test')
'D:\\test'

>>> win32file.GetFullPathName('C:/test')
'C:\\test'