Day04 Sqlite數據庫

源代碼: https://github.com/ltoddy/flask-tutorial

技術交流群:630398887(歡迎一起吹牛)

用到的數據庫是sqlite,這個數據庫不需要安裝,只要你電腦能運行C語言就行(是個能開機的電腦就可以……)。

安裝:

pip install flask-sqlalchemy

或者通過pycharm內置的pip安裝

這里說一下數據庫URL(待會要用到)。就是說阿,如果你要鏈接數據庫,得先告訴程序數據庫在哪,無論是local的或者remote的。URL就是那個數據庫的位置。

數據庫引擎 URL
SQLite(Unix) sqlite:////absolute/path/to/database
SQLite(Windows) sqlite:///c:/absolute/path/to/database

不同的系統對于SQLite的URL是有一點不同的,我說一下原因,在Unix系統家族中,有一個根目錄"/",Unix系統是不分盤符的,也就是沒有C盤,D盤之類的,所有東西都在根目錄之下。而windows系統呢是分盤符的,比如你有東西在C盤,那么對于C盤來說,它的根目錄也就是c:/所以說,對于這兩個系統數據庫URL的切換,只需要'/'與'c:/'互相轉換一下就好了。

配置數據庫:

from flask_sqlalchemy import SQLAlchemy
import os

basedir = os.path.abspath(os.path.dirname(__file__))
# 我們要把數據庫放在當下的文件夾,這個basedir就是當下文件夾的絕對路徑

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + \
                                        os.path.join(basedir, 'data.sqlite')
# 這里注意看,寫的是URI(統一資源標識符)
app.config['SQLALCHEMY_COMMIT_TEARDOWN'] = True
# SQLALCHEMY_COMMIT_TEARDOWN 因為數據庫每次有變動的時候,數據改變,但不會自動的去改變數據庫里面的數據,
# 只有你去手動提交,告訴數據庫要改變數據的時候才會改變,這里配置這個代表著,不需要你手動的去提交了,自動幫你提交了。
# 待會會有演示
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)

簡單說一下數據庫:
正規點的定義就是:數據庫是長期存儲在計算機內,大量有組織可共享的數據的集合。

簡單點就是,比如你有一個database(數據庫),數據庫中有很多表格,就像excel那樣子。
表格中有每一列的名字(字段),用來標記每一列是存的什么信息。就這么簡單,當然數據還會有些特殊的屬性,比如primary key, unique, not null等等。

OK,我們來定義一下我們的表格。這個項目為了簡單,只設立一個User表。用來之后的注冊用的。

class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    # 如果你學過數據庫的話就知道我們一般通過id來作為主鍵,來找到對應的信息的,通過id來實現唯一性
    name = db.Column(db.String(64), unique=True)

下面將有一堆知識點,沒空看的話就跳過去好了,等遇到了再來查看。
我復制的,太多了手打得類似我。

常見的SQLALCHEMY列類型

類型名稱 python類型 描述
Integer int 常規整形,通常為32位
SmallInteger int 短整形,通常為16位
BigInteger int或long 精度不受限整形
Float float 浮點數
Numeric decimal.Decimal 定點數
String str 可變長度字符串
Text str 可變長度字符串,適合大量文本
Unicode unicode 可變長度Unicode字符串
Boolean bool 布爾型
Date datetime.date 日期類型
Time datetime.time 時間類型
Interval datetime.timedelta 時間間隔
Enum str 字符列表
PickleType 任意Python對象 自動Pickle序列化
LargeBinary str 二進制

常見的SQLALCHEMY列選項

可選參數 描述
primary_key 如果設置為True,則為該列表的主鍵
unique 如果設置為True,該列不允許相同值
index 如果設置為True,為該列創建索引,查詢效率會更高
nullable 如果設置為True,該列允許為空。如果設置為False,該列不允許空值
default 定義該列的默認值

數據庫操作

創建表

python blog.py shell
>>> from hello import db
>>> db.create_all()

刪除表

db.drop_all()

插入行

#創建對象,模型的構造函數接受的參數是使用關鍵字參數指定的模型屬性初始值。
admin_role = Role(name='Admin')
user_role = Role(name='User')
user_susan = User(username='susan', role=user_role)#role 屬性也可使用,雖然它不是真正的數據庫列,但卻是一對多關系的高級表示。
user_john = User(username='john', role=admin_role)
#這些新建對象的 id 屬性并沒有明確設定,因為主鍵是由 Flask-SQLAlchemy 管理的。
print(admin_role.id)#None
#通過數據庫會話管理對數據庫所做的改動,在 Flask-SQLAlchemy 中,會話由 db.session 表示。
##首先,將對象添加到會話中
db.session.add(admin_role)
db.session.add(user_role)
db.session.add(user_susan)
db.session.add(user_john)
#簡寫:db.session.add_all([admin_role, user_role, user_john, user_susan])
##通過提交會話(事務),將對象寫入數據庫
db.session.commit()

修改行

admin_role.name = 'Administrator'
db.session.add(admin_role)
session.commit()

刪除行

db.session.delete(mod_role)
session.commit()

查詢行

查詢全部。Role.query.all()
條件查詢(使用過濾器)。User.query.filter_by(role=user_role).all()
user_role = Role.query.filter_by(name='User').first()#filter_by() 等過濾器在 query 對象上調用,返回一個更精確的 query 對象。

常用過濾器

過濾器 說 明
filter() 把過濾器添加到原查詢上,返回一個新查詢
filter_by() 把等值過濾器添加到原查詢上,返回一個新查詢
limit() 使用指定的值限制原查詢返回的結果數量,返回一個新查詢
offset() 偏移原查詢返回的結果,返回一個新查詢
order_by() 根據指定條件對原查詢結果進行排序,返回一個新查詢
group_by() 根據指定條件對原查詢結果進行分組,返回一個新查詢

最常使用的SQLAlchemy查詢執行函數

方 法 說 明
all() 以列表形式返回查詢的所有結果
first() 返回查詢的第一個結果,如果沒有結果,則返回 None
first_or_404() 返回查詢的第一個結果,如果沒有結果,則終止請求,返回 404 錯誤響應
get() 返回指定主鍵對應的行,如果沒有對應的行,則返回 None
get_or_404() 返回指定主鍵對應的行,如果沒找到指定的主鍵,則終止請求,返回 404 錯誤響應
count() 返回查詢結果的數量
paginate() 返回一個 Paginate 對象,它包含指定范圍內的結果

OK,知識點到此為止。

我們來操作一下數據庫:
更改這個路由

@app.route('/', methods=['GET', 'POST'])
def index():

代碼如下:

@app.route('/', methods=['GET', 'POST'])
def index():
    form = NameForm()
    if form.validate_on_submit():
        user = User.query.filter_by(name=form.name.data)
        if user is None:
            user = User(name=form.name.data)
            db.session.add(user)
            session['known'] = False
        else:
            session['known'] = True
        session['name'] = form.name.data
        form.name.data = ''
        return redirect(url_for('index'))
    return render_template('index.html',
                           form=form, name=session.get('name'),
                           known=session.get('known', False))

注意看 db.session.add(user)。

假設沒有app.config['SQLALCHEMY_COMMIT_TEARDOWN'] = True 這行代碼。

那么那行db.session.add(user)的后面需要加上db.session.commit()才可以把數據放到數據庫中。

對應的
/templates/index.html也要更改一下:

{% extends 'base.html' %}
{% import 'bootstrap/wtf.html' as wtf %}
{% block page_content %}
    <div class="page-header">
        <h1>Hello {% if name %}{{ name }}{% else %}stranger!{% endif %}</h1>
        {% if not known %}
            <p>Nice to meet you!</p>
        {% else %}
            <p>Happy to see you again!</p>
        {% endif %}
    </div>
    {{ wtf.quick_form(form) }}
{% endblock %}

說一下,如果你要運行項目,然后打開頁面可能會出現一些SQLAlchemy的異常,這個時候,首先去看一下

app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + \
                                        os.path.join(basedir, 'data.sqlite')

這個,我們關心的是最后data.sqlite這個文件是否存在。
如果你沒有發現這個文件的話,那么打開terminal(pycharm已經集成好了).

python3 blog.py shell
>>> from blog import *
>>> db # 這一行目的是看看db被添加進來了么。
<SQLAlchemy engine=sqlite:////home/me/PycharmProjects/blog/data.sqlite>
>>> db.drop_all()
>>> db.create_all()

這個樣子你就會看到data.sqlite出現在你的文件夾中了。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,517評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,087評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,521評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,493評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,207評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,603評論 1 325
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,624評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,813評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,364評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,110評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,305評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,874評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,532評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,953評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,209評論 1 291
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,033評論 3 396
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,268評論 2 375

推薦閱讀更多精彩內容