Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
380 views
in Technique[技术] by (71.8m points)

python - Confusion about URI path to configure SQLite database

Hi I am building a web application using Flask and Sqlite3. I had issues with connecting the database for a while and it did not work when I wrote this:

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

Python gave me operational error: can not open database because I wrote with 4 slashes after the colon. After reading sqlalchemy documentation and doing so many trials, I found out this worked:

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

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

or this with 4 slashes but no C:

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

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

I am confused because based on the documentation of connecting strings: The file specification for the SQLite database is taken as the “database” portion of the URL. Note that the format of a SQLAlchemy url is:

driver://user:pass@host/database

This means that the actual filename to be used starts with the characters to the right of the third slash. So connecting to a relative filepath looks like:

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

An absolute path, which is denoted by starting with a slash, means you need four slashes:

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

SO according to this, if I use absolute path, I need 4 slashes, but when I did that with version 1, python gave me errors. And when I used 3 slashes for absolute path in version 2, it worked.

So I am really confused. Can anyone explain for me why ? I would really appreciate it. Thank you

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You are correct about the database component being read as all the characters after the third slash. Here's the parsed: version 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': {}}

In Windows, a slash at the beginning of a path gets normalized to "the root drive of the current working directory". Using pywin32, we can call GetFullPathName to view the normalized version of a path:

>>> 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'

The reason version 1 doesn't work is because specifying both a leading slash and a drive letter will get normalized by Windows into an invalid path. (More specifically, the path is invalid because colons are not allowed in Windows paths, except at the beginning as a drive specifier.)

To show how a leading slash is normalized differently depending on the environment, let's change the current working directory to one on another drive and check out the normalized path:

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

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

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...