Day04 Sqlite數據庫

Day04 Sqlite數據庫

源代碼: https://github.com/LToddy/blog

技術交流羣: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出現在你的文件夾中了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章