Flask-SQLAIchemy插件
另外一個框架Flask-SQLAIchemy,是對SQLAIchemy進行一個簡單的封裝编曼,使得我們在Flask中使用sqlalchemy更加簡單豆巨,可以通過pip install flask-sqlalchemy。
掐场。數(shù)據(jù)庫初始化:數(shù)據(jù)庫初始化不再通過create_engine
1 from flask import Flask
2 from flask_sqlalchemy import SQLAlchemy
3 from constants import DB_URI
4 app = Flask(__name__)
5 app.config['SQLALCHEMY_DATABASE_URI'] = DB_URI
6 db = SQLAlchemy(app)
往扔。ORM類:之前都是通過Base = declarative_base()來初始化一個基類,然后再繼承熊户,在Flask-SQLAIchemy中更加簡單了
1 class User(db.Model):
2? ?id = db.Column(db.Integer,primary_key=True)
3? ?username = db.Column(db.String(80),unique=True)
4? ?email = db.Column(db.String(120),unique=True)
5
6? ?def __repr__(self):
7? ? ? ? return '<User %s>' % self.username
映射模型到數(shù)據(jù)庫表:使用Flask-SQLAIchemy所有類都是繼承自db.Model萍膛,并且所有的Column和數(shù)據(jù)類也都成為db的一個屬性。但有個好處是不用寫表名了嚷堡,F(xiàn)lask-SQLAIchemy會自動將類名小寫化蝗罗,然后映射成表名。
寫完模型后蝌戒,要將模型映射到數(shù)據(jù)庫的表名中串塑,使用以下代碼創(chuàng)建所有的表:
1 db.create_all()
。添加數(shù)據(jù):這時候可以在數(shù)據(jù)庫中看到已經(jīng)生成了一個user表了北苟。
1 admin = User('admin','admin@example.com')
2 guest = User('guest','guest@example.com')
3 db.session.add(admin)
4 db.session.add(guest)
5 db.session.commit()
桩匪。添加數(shù)據(jù)和之前的沒有區(qū)別,只是session成為一個db的屬性友鼻。
傻昙。查詢數(shù)據(jù)不再是之前的session.query了,而是將query屬性放在了db.Model.query的方式進行查詢了
1 users = User.query.all()
彩扔。刪除數(shù)據(jù):刪除數(shù)據(jù)跟添加數(shù)據(jù)類似屋匕,只不過session是db的一個屬性而已:
1 db.session.delete(admin)
2 db.session.commit()
Flask-Script
Flask-Script 的作用是可以通過命令行的形式來操作Flask。例如通過命令跑一個開發(fā)版本的服務(wù)器借杰、設(shè)置數(shù)據(jù)庫过吻,定時任務(wù)等。要使用Flsk-Script蔗衡,可以通過pip install flask-script 安裝最新版本
1 from flask_script import Manager
2 from your_app import app
3?
4 manager = Manager(app)
5
6 @manager.command
7 def hello():
8? ? ? ?print('hello')
9
10 if __name__ == '__main__':
11? ? ? ?manager.run()
我們把腳本命令代碼放在一個叫做manage.py文件中纤虽,然后在終端運行python manage.py hello命令,就可以看到輸出hello了
定義命令的三種方法
1.使用@command裝飾器
2.使用類繼承自Command類
1 from flask_script import Command,Manager
2 from your_app import app
3
4 manager = Manager(app)
5
6 class Hello(Command):
7? ? ? ? "prints hello world"
8
9? ? ? ? def run(self):
10? ? ? ? ? ? print("hello world")
11
12 manager.add_command('hello',Hello())
使用類的方式绞惦,有三點需要注意
逼纸。必須繼承自Command基類
。必須實現(xiàn)run方法济蝉。
杰刽。必須通過方法添加命令菠发。
3.使用option裝飾器:如果想要在命令時還傳遞參數(shù)進去,那么使用@option裝飾器更加方便
1 @manager.option('-n','--name',dest='name')
2 def hello(name):
3? ? ? ? print('hello ',name)
這樣贺嫂,調(diào)用hello命令
1 python manage.py -n juran
2 python manage.py --name juran
添加參數(shù)到命令中
滓鸠。option裝飾器:以上三種創(chuàng)建命令方式都可以添加參數(shù), @option裝飾器第喳,已經(jīng)介紹過了
1 @manager.option('-n', '--name', dest='name', default='joe')
2 @manager.option('-u', '--url', dest='url', default=None)
3 def hello(name, url):
4? ? ?if url is None:
5? ? ? ? ?print("hello", name)
6? ? ?else:
7? ? ? ? ? ?print("hello", name, "from", url)
糜俗。command裝飾器:command裝飾器也可以添加參數(shù),但是不能那么的靈活
1 @manager.command
2 def hello(name="Fred")
3? ? ?print("hello", name)
曲饱。類繼承:類繼承也可以添加參數(shù)
1 from flask_Flask import Comman,Manager,Option
2
3 class Hello(Command):
4? ? ?option_list = (
5? ? ? ? ? Option('--name','-n',dest='name'),
6? ?)
7
8? ?def run(self,name):
9? ? ? ? ?print("hello %s" % name)
如果要在指定參數(shù)時悠抹,動態(tài)的做一些事情,可以使用get_options方法
1 class Hello(Command):
2? ?def __init__(self,default_name='Joe'):
3 self.default_name = default_name
4
5? ? ?def get_options(self):
6? ? ? ? ? return [
7? ? ? ? ? ? ? ?Option('-n','--name',dest='name',default=self.default_name),
8? ? ? ]
9
10? ? ? def run(self,name):
11? ? ? ? ? ? print('hello',name)
Flask-Migrate
在實際的開發(fā)環(huán)境中扩淀,經(jīng)常會發(fā)生數(shù)據(jù)庫修改的行為楔敌。一般不會手動去修改,而是去修改ORM對應的模型驻谆,然后再把模型映射到數(shù)據(jù)庫中梁丘。這時如果有一個工具能專門做這種事情,就顯得非常有用了旺韭,而flask-migrate就是組這個事情的氛谜。flask-migrate是基于Alembic進行的一個封裝,并集成到Flask中区端,而所有的遷移操作其實是Alembic做的值漫,它能跟蹤模型的變化,并將變化映射到數(shù)據(jù)庫中织盼。
使用Flask-Migrate需要安裝
1 pip install flask-migrate
要讓Flask-Migrate能夠管理app中的數(shù)據(jù)庫杨何,需要使用Migrate(app,db)來綁定app和數(shù)據(jù)庫
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from constants import DB_URI
from flask_migrate import Migrate
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = DB_URI
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)
# 綁定app和數(shù)據(jù)庫
migrate = Migrate(app,db)
class User(db.Model):
? ? id = db.Column(db.Integer,primary_key=True)
? ? username = db.Column(db.String(20))
? ? addresses = db.relationship('Address',backref='user')
class Address(db.Model):
? ? id = db.Column(db.Integer,primary_key=True)
? ? email_address = db.Column(db.String(50))
? ? user_id = db.Column(db.Integer,db.ForeignKey('user.id'))
db.create_all()
@app.route('/')
def hello_world():
? ? return 'Hello World!'
if __name__ == '__main__':
? ? app.run()
初始化一個遷移文件夾
1 flask db init
然后再把當前的模型添加到遷移文件中
1 flask db migrate
最后再把遷移文件中對應的數(shù)據(jù)庫操作,真正的映射到數(shù)據(jù)庫中
1?flask db upgrade
manage.py文件
這個文件用來存放映射數(shù)據(jù)庫的命令沥邻,MigrateCommand是flask-migrate集成的一個命令危虱,因此想要添加到腳本命令中,想要采用manager.add_command('db',MigrateCommand)的方式唐全,以后運行python manager.py dbxxx的命令埃跷,其實就是執(zhí)行MigrateCommand。
1 from flask_script import Manager
2 from flask_migrate import MigrateCommand, Migrate
3 from exts import db
4 from demo import app
5 from models import User
6
7 manage = Manager(app)
8 Migrate(app, db)
9 manage.add_command("db", MigrateCommand)
10
11 if __name__ == '__main__':
12? ? ? manage.run()