a.導庫:
import pymysql
from flask_sqlalchemy import SQLAlchemy
b.
# 建立程序實例
app = Flask(__name__)
# 數據庫配置:數據庫地址/關閉自動跟蹤修改
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://Juliet:123456@127.0.0.1/flask_books'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# 設置secret_key
app.secret_key = 'dev'
# 建立數據庫對象
pymysql.install_as_MySQLdb()
db = SQLAlchemy(app)
複製代碼
定義書和做者模型
class Author(db.Model):
'''做者模型'''
__tablename__ = 'authors'
# 字段
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(16),unique=True)
# 關係引用
# books是給本身(Author模型)用的,author是給Book模型用的
books = db.relationship('Book',backref='author')
def __repr__(self):
return 'Author:%s'% self.name
class Book(db.Model):
'''書籍模型'''
__tablename__ = 'books'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(16), unique=True)
author_id = db.Column(db.Integer,db.ForeignKey('authors.id'))
def __repr__(self):
return 'Book:%s'% self.name
複製代碼
db.drop_all()
db.create_all()
複製代碼
a.在Flask-SQLAlchemy中,插入、修改、刪除操做,均由數據庫會話管理,用db.session表示
b.在準備把數據寫入數據庫前,要先將數據添加到會話中而後調用commit()方法提交會話
c.提交操做把會話對象所有寫入數據庫,若是寫入過程發生錯誤,整個會話都會失效,據庫會話也能夠回滾,
經過db.session.rollback()方法,實現會話提交數據前的狀態
d.在Flask-SQLAlchemy中,查詢操做是經過query對象操做數據。最基本的查詢是返回表中全部數據,能夠經過過濾器進行更精確的數據庫查詢
複製代碼
在開發過程當中,須要修改數據庫模型,並且還要在修改以後更新數據庫。最直接的方式就是刪除舊錶,但這樣會丟失數據。 更好的解決辦法是使用數據庫遷移框架,它能夠追蹤數據庫模式的變化,而後把變更應用到數據庫中。python
參考:juejin.im/post/5cc7fb…mysql
導包:須要安裝Flask-Script和flask-migrate
配置:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import pymysql
from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager
pymysql.install_as_MySQLdb()
app = Flask(__name__)
# 經過腳本管理flask程序
manager = Manager(app)
# 設置鏈接數據庫的URL
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:123456@127.0.0.1:3306/db_flask'
# 設置每次請求結束後會自動提交數據庫中的改動
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
# 數據庫和模型類同步修改
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
# 查詢時會顯示原始SQL語句
app.config['SQLALCHEMY_ECHO'] = True
db = SQLAlchemy(app)
# 建立數據庫遷移對象
Migrate(app, db)
# 向腳步管理添加數據庫遷移命令 db指命令的別名
manager.add_command('db', MigrateCommand)
# 類型
class Type(db.Model):
# 表名
__tablename__ = 'tbl_types'
# 數據庫真正存在的字段
id = db.Column(db.Integer, primary_key=True) # 主鍵
name = db.Column(db.String(32), unique=True) # 名字
# 數據庫中不存在的字段,只是爲了查找和反向查找。
# backref:在關係的另外一模型中添加反向引用
heros = db.relationship("Hero", backref='type')
def __repr__(self):
return self.name
# 英雄
class Hero(db.Model):
# 表名
__tablename__ = 'tbl_heros'
# 數據庫真正存在的字段
id = db.Column(db.Integer, primary_key=True) # 主鍵
name = db.Column(db.String(64), unique=True) # 名字
gender = db.Column(db.String(64)) # 性別
# 外鍵 一個射手對應不少英雄
type_id = db.Column(db.Integer, db.ForeignKey("tbl_types.id"))
def __repr__(self):
return self.name
if __name__ == '__main__':
# 0.0.0.0表明任何能表明這臺機器的地址均可以訪問
# app.run(host='0.0.0.0', port=5000) # 運行程序
manager.run()
首先咱們經過命令建立出migrations文件夾,後面全部的遷移文件都會放在這個文件夾裏面
python flask_migrate_db.py db init
下面這條命令跟咱們Django裏面的makemigrations同樣,是生成遷移文件的做用。由於咱們的模型類並無添加或刪除字段,全部第一次會出現沒有改變的提示。 -m:給遷移文件加上註釋
python flask_migrate_db.py db migrate -m 'first create'
添加新字段 咱們在英雄裏面添加一個年齡字段,再遷移一下:
python flask_migrate_db.py db migrate -m 'add age'
生成遷移文件,這個時候數據庫並無改變,咱們還要用upgrade命令同步到數據庫中:
python flask_migrate_db.py db upgrade
age字段已經添加到數據庫當中了。
回退:
回退數據庫時,須要指定回退版本號,因爲版本號是隨機字符串,爲避免出錯,建議先使用python flask_migrate_db.py db history命令查看歷史版本的具體版本號,而後複製具體版本號執行回退。
回退到原始版本:
python flask_migrate_db.py db downgrade base
回退到指定版本:
python flask_migrate_db.py db downgrade 4cee71e47df3
複製代碼
from flask import Flask
from flask_mail import Mail,Message
app = Flask(__name__)
#配置郵件:服務器/端口/傳輸層安全協議/郵箱名/密碼
app.config.update(
DEBUG = True,
MAIL_SERVER='smtp.qq.com',
MAIL_PROT=465,
MAIL_USE_TLS = True,
MAIL_USERNAME = '876972931@qq.com',
MAIL_PASSWORD = 'mkdggikrxfxkbcee', # 郵箱的SMTP受權碼
)
mail = Mail(app)
@app.route('/')
def index():
# sender 發送方,recipients 接收方列表
msg = Message("This is a test message!",sender="876972931@qq.com",recipients=['876972931@qq.com','837053035@qq.com'])
# 郵件內容
msg.body = "Flask Test Mail"
mail.send(msg)
print("Mail Sent!")
return "Sent Success!!"
if __name__ == '__main__':
app.run()
複製代碼
a.一對一模型 案例:一篇文章只對應一個內容sql
# 文章模型
class Article(db.Model):
# 表名
__tablename__ = 'tbl_article'
# 數據庫真正存在的字段
id = db.Column(db.Integer, primary_key=True) # 主鍵
title = db.Column(db.String(128), unique=True) # 名字
# 方便查找,數據並不存在的字段
content = db.relationship('Acontent', backref='article', uselist=False) #一對一須要把uselist設置爲False
# 內容模型
class Acontent(db.Model):
# 表名
__tablename__ = 'tbl_acontent'
# 數據庫真正存在的字段
id = db.Column(db.Integer, primary_key=True) # 主鍵
content = db.Column(db.Text(4000)) # 名字
article_id = db.Column(db.Integer, db.ForeignKey('tbl_article.id'))
複製代碼
b.一對多模型 案例:一個分類下有不少文章數據庫
# 分類模型
class Category(db.Model):
# 表名
__tablename__ = 'tbl_category'
# 數據庫真正存在的字段
id = db.Column(db.Integer, primary_key=True) # 主鍵
name = db.Column(db.String(32), unique=True) # 名字
# 方便查找,數據並不存在的字段
article = db.relationship('Article', backref='category')
# 文章模型
class Article(db.Model):
# 表名
__tablename__ = 'tbl_article'
# 數據庫真正存在的字段
id = db.Column(db.Integer, primary_key=True) # 主鍵
title = db.Column(db.String(128), unique=True) # 名字
category_id = db.Column(db.Integer, db.ForeignKey('tbl_category.id')) # 分類id
# 方便查找,數據並不存在的字段
content = db.relationship('Acontent', backref='article', uselist=False) # 一對一須要把uselist設置爲False
複製代碼
c.多對多模型 案例:一個標籤對應不少文章,一篇文章也對應不少標籤flask
# 輔助表
tbl_tags = db.Table('tbl_tags',
db.Column('tag_id', db.Integer, db.ForeignKey('tbl_tag.id')),
db.Column('article_id', db.Integer, db.ForeignKey('tbl_article.id'))
)
# 標籤模型
class Tag(db.Model):
# 表名
__tablename__ = 'tbl_tag'
# 數據庫真正存在的字段
id = db.Column(db.Integer, primary_key=True) # 主鍵
name = db.Column(db.String(32), unique=True) # 名字
# 文章模型
class Article(db.Model):
# 表名
__tablename__ = 'tbl_article'
# 數據庫真正存在的字段
id = db.Column(db.Integer, primary_key=True) # 主鍵
title = db.Column(db.String(128), unique=True) # 名字
category_id = db.Column(db.Integer, db.ForeignKey('tbl_category.id')) # 分類id
# 方便查找,數據並不存在的字段
content = db.relationship('Acontent', backref='article', uselist=False) # 一對一須要把uselist設置爲False
tags = db.relationship('Tag', secondary=tbl_tags, backref='articles')
複製代碼
d.自關聯模型 案例:地區安全
# 地區模型
class Area(db.Model):
# 表名
__tablename__ = "tbl_area"
# 數據庫真正存在的字段
id = db.Column(db.Integer, primary_key=True) # 主鍵
name = db.Column(db.Text, nullable=False) # 地區名字
parent_id = db.Column(db.Integer, db.ForeignKey("tbl_area.id")) # 父評論id
# 方便查找,數據並不存在的字段
parent = db.relationship("Area", remote_side=[id]) # 自關聯須要加remote_side
複製代碼