在Flask中使用mySQL


在“FlaskWeb開發:基於Python的Web應用開發實戰“一書中,作者為了簡便以及更側重於Flask而不是數據庫的說明,所以書中使用了SQLite數據庫。

但是實際應用中mySQL應該更廣泛一些。所以嘗試使用mySQL替代書中原代碼中SQLite數據庫的功能。

平台說明:

Ubuntu 16.04 4.8.0-36-generic (安裝在VMware上)

  1. 第一個需要注意的就是,與SQLite不同的是,Flask-SQLAlchemy並不會為mySQL主動去建立一個database。所以需要自己手動在mySQL中建立一個相應的數據庫,然后才能使用Flask-SQLAlchemy對相應數據進行查找,驗證等操作。如果沒有事先創建,是不能使用mySQL的。
    所以第一個步驟就是在mySQL上創建數據庫,這里使用sql腳本進行創建,並且使用的是本機的mySQL。
    使用命令:mysql -u root -p
    然后輸入安裝mySQL時設置的密碼登入mySQL。
    然后使用命令:source data_test.sql執行事先寫好的sql腳本,創建相應數據庫。這里我是在腳本目錄執行的,如果不是需要指定完整路徑。
    data_test.sql文件內容如下。該腳本與書中的models.py內容對應。表,表頭一一對應,但是功能不一定能一一對應,對mySQL不是很熟悉。
     1 drop database if exists data_test;
     2 create database data_test;
     3 use data_test;
     4 CREATE TABLE roles(
     5     id INT(11) NOT NULL AUTO_INCREMENT,
     6     name VARCHAR(255) COLLATE utf8_bin NOT NULL,
     7     UNIQUE (name),
     8     permissions INT(11),
     9     `default` BOOLEAN DEFAULT FALSE,
    10     INDEX(`default`),
    11     PRIMARY KEY (id)
    12 ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
    13 AUTO_INCREMENT=1;
    14 
    15 CREATE TABLE users(
    16     id INT(11) NOT NULL AUTO_INCREMENT,
    17     username VARCHAR(255) COLLATE utf8_bin NOT NULL,
    18     UNIQUE (username),
    19     email VARCHAR(255) COLLATE utf8_bin NOT NULL,
    20     UNIQUE (email),
    21     INDEX(username,email),
    22     password_hash VARCHAR(255) COLLATE utf8_bin NOT NULL,
    23     role_id INT(11),
    24     confirmed BOOLEAN DEFAULT FALSE,
    25     name VARCHAR(255),
    26     location VARCHAR(255),
    27     about_me TEXT,
    28     member_since datetime DEFAULT CURRENT_TIMESTAMP,
    29     last_seen datetime DEFAULT CURRENT_TIMESTAMP,
    30     avatar_hash VARCHAR(255),
    31     followed INT(11),
    32     followers INT(11),
    33     FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE,
    34     PRIMARY KEY (id)
    35 ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
    36 AUTO_INCREMENT=1;
    37 
    38 CREATE TABLE posts(
    39     id INT(11) NOT NULL AUTO_INCREMENT,
    40     body TEXT,
    41     body_html TEXT,
    42     timestamp datetime DEFAULT CURRENT_TIMESTAMP,
    43     INDEX(timestamp),
    44     author_id INT(11),
    45     FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE CASCADE,
    46     PRIMARY KEY (id)
    47 ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
    48 AUTO_INCREMENT=1;
    49 
    50 CREATE TABLE follows(
    51     follower_id INT(11),
    52     constraint con_follower FOREIGN KEY (follower_id) REFERENCES users(id),
    53     followed_id INT(11),
    54     constraint con_followed FOREIGN KEY (followed_id) REFERENCES users(id),
    55     PRIMARY KEY (follower_id,followed_id),
    56     timestamp datetime DEFAULT CURRENT_TIMESTAMP
    57 )ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
    58 
    59 CREATE TABLE comments(
    60     id INT(11) NOT NULL AUTO_INCREMENT,
    61     body TEXT,
    62     body_html TEXT,
    63     timestamp datetime DEFAULT CURRENT_TIMESTAMP,
    64     INDEX(timestamp),
    65     disabled BOOLEAN,
    66     author_id INT(11),
    67     post_id INT(11),
    68     FOREIGN KEY (author_id) REFERENCES users(id) ON DELETE CASCADE,
    69     FOREIGN KEY (post_id) REFERENCES posts(id) ON DELETE CASCADE,
    70     PRIMARY KEY (id)
    71 ) ENGINE=INNODB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
    72 AUTO_INCREMENT=1;

    執行后,mySQL應該可以查詢到新建的表。

     

  2. config文件中對數據庫進行設置

    SQLALCHEMY_DATABASE_URI 使用的如下配置:
    class TestingConfig(Config):
    TESTING = True
    SQLALCHEMY_DATABASE_URI = "mysql+pymysql://root:password@localhost:3306/data_test"
    然后就可以使用Flask-SQLAlchemy對數據庫進行操作,而不必去mySQL中操作了。

整個過程中對我來說,比較困難的應該算是將Flask-SQLAlchemy中的關系映射到mySQL數據庫中,其中有個地方值得注意:

  • SQLAlchemy中的relationship。
    例如:roles表中有users = db.relationship('User', backref='role', lazy='dynamic')這句。對應到mySQL其實就是一個外鍵,並且是在users表中定義的,即users中的role_id都必須是從表roles的id字段中引用過來的。如果在users中添加一個role,並且其id並不存在與role中,那么就會報錯。
    其中的參數backref表明該關系為雙向,這樣就不需要再users再定義一個relationship了。而lazy設為dynamic即表明查詢的時候不直接加載結果,而是返回一個查詢對象,這樣就可以加過濾對查詢結果進行篩查。

實踐過程中參考了下面鏈接:

對外建的理解

外鍵constraint關鍵字

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM