嗨,我正在使用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个斜杠作为绝对路径时,它起作用了。
所以我真的很困惑。谁能为我解释为什么?我真的很感激。谢谢
答案 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'