Flask-SQLAlchemy是一個Flask擴展,簡化了在Flask應用中使用SQLAlchemy的操做。SQLAlchemy提供了高層ORM,也提供了使用數據庫原生SQL的低層功能。python
# 安裝 pip install flask-sqlalchemy
在Flask-SQLAlchemy中,數據庫使用URL指定。mysql
應用使用的數據庫URL必須保存到Flask配置對象的 SQLALCHEMY_DATABASE_URI 鍵中。git
建議把 SQLALCHEMY_TRACK_MODIFICATIONS 鍵 設爲 False,以便在不須要跟蹤對象變化時下降內存消耗。sql
from flask import Flask # 1.導入 from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) #2.定義要鏈接的數據庫 DB_URI = "mysql+pymysql://root:123456@127.0.0.1:3306/learn_sqlalchemy?charset=utf8" #3.添加到到配置中 app.config['SQLALCHEMY_DATABASE_URI'] = DB_URI app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] =False # 4.實例化一個對象,將app傳進去 db = SQLAlchemy(app) @app.route('/') def hello_world(): return 'Hello World!' if __name__ == '__main__': app.run()
class User(db.Model): __tablename__ = 'user' id = db.Column(db.Integer,primary_key=True,autoincrement=True) username = db.Column(db.String(50),nullable=False) def __repr__(self): return self.username class Article(db.Model): __tablename__ = "article" id = db.Column(db.Integer, primary_key=True, autoincrement=True) title = db.Column(db.String(50), nullable=False) uid = db.Column(db.Integer,db.ForeignKey("user.id")) author = db.relationship("User",backref='article') def __repr__(self): return self.title
__tablename__ 定義在數據庫中的表名。shell
例:一個角色對應多個用戶:數據庫
class Role(db.Model): # ... users = db.relationship('User', backref='role') class User(db.Model): # ... role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
db.relationship()中的第一個參數指的是這個關係的另外一端是哪一個模型,backref參數向User模型添加一個role屬性,從而定義反向關係。flask
# 建立表 db.create_all() # 刪除表 db.drop_all() # 插入行 admin_role = Role(name='admin') user_role= User(username='hyp', role=admin_role) # 對數據庫的改動童年過數據庫會話管理,在Flask-SQLAlchemy中,會話由 db.session 表示。在寫入數據庫以前,要先添加到會話中: db.session.add(admin_role) db.session.add(user_role) # 或者 db.session.add_all([admin_role, user_role]) # 爲了寫入數據庫,要調用 commit()方法提交會話: db.session.commit() # 數據庫回話能保證數據庫的一致性。數據庫回話也能夠回滾,調用 db.session.rollback() # 修改行 admin_role.name= 'lcy' db.session.add(admin_role) db.session.commit() # 刪除行 db.session.delete(admin_role) db.session.commit() # 注意:刪除、更新和插入同樣,提交數據會話才執行。 # 查詢行 # 每一個模型類都提供了query對象。 Role.query.all() Role.query.filter_by(role=user_role).all() # 查看生成的原生SQL查詢語句,只須要把query對象轉換成字符串: str(User.query.filter_by(role=user_role)) # first()方法 只返回第一個結果 user_role = Role.query.filter_by(name='User').first()
若想把對象添加到入列表中,必須使用 app.shell_context_processor 裝飾器建立並註冊一個shell上下文處理器。session
@app.shell_context_processor def make_shell_context(): return dict(db=db, User=User, Role=Role)
這個shell上下文處理器函數返回一個字典,包含數據庫實例和模型。app
Flask應用還可使用Flask-Migrate擴展,是對Alembic的輕量級包裝。ide
# 安裝 pip install flask-migrate
manage.py
from flask_script import Manager from flask_migrate_demo import app from exts import db import models #這個必定要導入 from flask_migrate import Migrate,MigrateCommand manager = Manager(app) Migrate(app,db) manager.add_command("db",MigrateCommand) #把全部命令放到db裏面 if __name__ == '__main__': manager.run()
初始化
python manage.py db init
建立遷移腳本
python manage.py db migrate -m '第一次提交'
生成到數據庫
python manage.py db upgrade
alembic是用來作ORM模型與數據庫的遷移與映射。alembic使用方式跟git有點相似,表如今兩個方面,第一個,alemibi的全部命令都是以alembic開頭;
第二,alembic的遷移文件也是經過版本進行控制的。
# 安裝 pip install alembic
使用:
# model.py from sqlalchemy import Column,Integer,String,create_engine from sqlalchemy.ext.declarative import declarative_base DB_URI = "mysql+pymysql://root:123456@127.0.0.1:3306/alembic_demo?charset=utf8" engine = create_engine(DB_URI) Base = declarative_base(engine) class User(Base): __tablename__ = 'user' id = Column(Integer,primary_key=True,autoincrement=True) username = Column(String(50),nullable=False)
在終端初始化,建立一個倉庫
alembic init learn_alembic
修改配置文件,指定鏈接的數據庫
# alembic.ini sqlalchemy.url = mysql+pymysql://root:123456@127.0.0.1:3306/alembic_demo?charset=utf8
將models所在的目錄路徑添加到env.py,並指定target_metadata
import sys,os # 1.__file__:當前文件(env.py) #2.os.path.dirname(__file__):獲取當前文件的目錄 #3.os.path.dirname(os.path.dirname(__file__)):獲取當前文件目錄的上一級目錄 #4.sys.path: python尋找導入的包的全部路徑 sys.path.append(os.path.dirname(os.path.dirname(__file__))) import models target_metadata = models.Base.metadata
生成遷移腳本
alembic revision --autogenerate -m "第一次提交"
將生成的遷移腳本映射到數據庫中
alembic upgrade head
之後若是想要添加或修改模型,重複最後兩步便可。
經常使用命令:
init:建立一個alembic倉庫 rebision:建立一個新的版本文件 --autogenerate:自動將當前模型的修改,生成遷移腳本 -m:本次遷移作了哪些修改 upgrade:將指定版本的遷移文件映射到數據庫中,會執行版本文件中的upgrade函數 head:表明當前的遷移腳本的版本號 downgrade:會執行指定版本的遷移文件中的downgrade函數 heads:展現當前可用的heads腳本文件 history:列出全部的遷移版本及其信息 current:展現當前數據庫中的版本號
經典錯誤 1.FAILED:Target databases is not up to date. 緣由:主要是heads和current不相同。current落後於heads的版本 解決辦法:將current移動到head上。alembic upgrade head 2.FAILED:Can't locate revision identified by 'xxxxxxx' 緣由:數據庫中存的版本號不在遷移腳本文件中 解決辦法:刪除數據的alembic_version表中的數據,從新執行alembic upgrade head
用alembic工具:數據庫中會自動生成一張表alembic_version
在數據庫中能夠查看當前的版本號
在cmd終端也能夠經過current命令查看
alembic current
1. config.py
DB_URI = "mysql+pymysql://root:123456@127.0.0.1:3306/flask_alembic_demo?charset=utf8" SQLALCHEMY_DATABASE_URI = DB_URI
(2)flask_alembic_demo.py
from flask import Flask from flask_sqlalchemy import SQLAlchemy import config app = Flask(__name__) app.config.from_object(config) db = SQLAlchemy(app) class User(db.Model): __tablename__ = 'user' id = db.Column(db.Integer,primary_key=True,autoincrement=True) username = db.Column(db.String(50),nullable=False) @app.route('/') def hello_world(): return 'Hello World!' if __name__ == '__main__': app.run()
(3)初始化
alembic init alembic
(4)alembic.ini
sqlalchemy.url = mysql+pymysql://root:123456@127.0.0.1:3306/flask_alembic_demo?charset=utf8
(5)env.py
import sys,os sys.path.append(os.path.dirname(os.path.dirname(__file__))) import flask_alembic_demo # 用的是db.Model target_metadata = flask_alembic_demo.db.Model.metadata
(6)生成遷移腳本
alembic revision --autogenerate -m "first commit"
(7)upgrade到數據庫
alembic upgrade head
(8)添加字段
假入想添加一個字段age
class User(db.Model): __tablename__ = 'user' id = db.Column(db.Integer,primary_key=True,autoincrement=True) username = db.Column(db.String(50),nullable=False) age = db.Column(db.Integer)
重複步驟便可
alembic revision --autogenerate -m "add column age" alembic upgrade head