flask(三)之Flask-SQLAlchemy

01-介紹

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

02-數據庫的鏈接

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()

 03-定義模型

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

04-一對多的關係

例:一個角色對應多個用戶:數據庫

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

 

05-操做

# 建立表
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()

06-集成Python Shell

若想把對象添加到入列表中,必須使用 app.shell_context_processor 裝飾器建立並註冊一個shell上下文處理器。session

@app.shell_context_processor
def make_shell_context():
    return dict(db=db, User=User, Role=Role)

這個shell上下文處理器函數返回一個字典,包含數據庫實例和模型。app

07-使用 Flask-Migrate實現數據庫遷移

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

08-alembic數據遷移工具

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

Flask-SQLAlchemy下使用alembic:

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
相關文章
相關標籤/搜索