當項目愈來愈大的時候 會出現不少問題css
ORM:中文件關係對象的映射 使用ORM去操做數據庫的時候 不會再去寫原生的SQL了 經過把表映射成 類 字段爲你的屬性 ORM在執行的時候 也會最終轉換爲 SQL語句 去操做數據庫html
安裝:python
sudo pip3 install flask-sqlalchemymysql
create database if not exists 庫名 character set utf8;sql
sudo pip3 install pymysql數據庫
DB_URI = 'mysql+pymysql://用戶名:密碼@主機:端口號/庫名'flask
實例安全
from sqlalchemy import create_engine DATABASE = 'hz03' USERNAME = 'root' PASSWORD = '123456' HOST = '127.0.0.1' PORT = '3306' #建立鏈接和操做數據庫的URI DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}'.format(USERNAME,PASSWORD,HOST,PORT,DATABASE) #建立操做數據庫的引擎 engine = create_engine(DB_URI) with engine.connect() as con: # con.execute('create table user(id int,username varchar(255),sex tinyint)') con.execute('insert into user values(1,"xxx",1)')
類型名 | 說明 |
---|---|
integer | 整形 |
SmallInteger | 小整形 |
BigInteger | 長整型 |
Float | 浮點型 |
String | varchar類型 |
Text | 長文本 |
Boolean | tingint |
Date | 日期 datetime.date |
Time | 時間 datetime.time |
DateTime | 時間和日期 datetime.datetim |
選項 | 選項說明 |
---|---|
primary_key | 主鍵 默認 False |
index | 常規 默認 False |
Unique | 惟一 默認 False |
nullable | 是否爲null 默認True |
default | 默認值 |
注意:session
其中的default默認值 並非更改表結構的默認值 而是在插入數據的時候 若是不插入數據 則插入默認值app
實例
from flask import Flask,render_template from flask_script import Manager from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) #建立鏈接數據的URI app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@127.0.0.1:3306/hz03' app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True #開啓自動提交 #數據的追蹤 當數據發生改變時 會返回信號量 進行關閉 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False db = SQLAlchemy(app) manager = Manager(app)
class User(db.Model): id = db.Column(db.Integer,primary_key=True) username = db.Column(db.String(20),index=True) age = db.Column(db.Integer) icon = db.Column(db.String(40),default='default.jpg')
@app.route('/create_table/') def create_table(): db.drop_all() #刪除 和當前模型類同名的表 db.create_all() #建立當前模型類的表 return '建立表' @app.route('/insert/') def insert(): try: u = User(username='張三',age=18) # print(u) db.session.add(u) db.session.commit() #由於sqlalchemy開啓事物 全部因此須要提交或者回滾 except: db.session.rollback() return '添加數據' #開啓了自動提交功能 不須要手動commit了 @app.route('/insert_two/') def insert_two(): u = User(username='李四',age=20) db.session.add(u) return '走我了' #修改 @app.route('/update/') def update(): u = User.query.get(1) # print(u.id) # print(u.username) u.username = '王五' db.session.add(u) return 'update' #刪除 @app.route('/delete/') def delete(): u = User.query.get(2) #查詢成功返回 對象 失敗返回None # print(u) db.session.delete(u) return '刪除'
project/ App/ __init__.py 包文件必須的 model.py 模塊 views.py 視圖 ext.py extensions.py 加載第三方擴展的文件 settings.py 配置文件 static/ templates/ manage.py 啓動項
project/ App/ __init__.py static/ js/ img/ upload/ css/ templates/ common/ ... forms/ __init__.py ... models/ __init__.py views/ __init.py__.py ... settings.py email.py extensions.py manager.py migrations/ venv/
建立模型類
class User(Base,db.Model): __tablename__ = 'user' #給表起名 id = db.Column(db.Integer,primary_key=True) username = db.Column(db.String(20),index=True) age = db.Column(db.Integer) icon = db.Column(db.String(40),default='default.jpg') def __init__(self,username='',age=0,icon='default.jpg'): self.username = username self.age = age self.icon = icon
@main.route('/add/') def add(): u = User(username='張三',age=18) db.session.add(u) db.session.commit() return '數據添加一條成功'
@main.route('/add_all/') def add_all(): u1 = User(username='李四',age=20) u2 = User(username='王五',age=22) db.session.add_all([u1,u2]) db.session.commit() return '添加多條'
class Base: #定義一個添加一條數據的方法 def save(self): try: db.session.add(self) db.session.commit() except: db.session.rollback() #定義添加多條數據的方法 @staticmethod def save_all(*args): try: db.session.add_all(args) db.session.commit() except: db.session.rollback() #自定義刪除方法 def delete(self): try: db.session.delete(self) db.session.commit() except: db.session.rollback()
使用
class User(Base,db.Model): ...
在視圖中使用
@main.route('/add/') def add(): # u = User(username='張三',age=18) u = User('張三',18) # db.session.add(u) # db.session.commit() u.save() #使用自定義的添加方法 return '數據添加一條成功' @main.route('/add_all/') def add_all(): # u1 = User(username='李四',age=20) # u2 = User(username='王五',age=22) u1 = User('趙六',27) u2 = User('李七',12) # db.session.add_all([u1,u2]) # db.session.commit() User.save_all(u1,u2) return '添加多條' @main.route('/delete/') def delete(): u = User.query.get(1) u.delete() return '刪除'
查詢數據的集合
分類
類名.query獲得的結果就爲原始查詢集
加上各類的過濾器的方法 最終返回的結果 爲數據查詢集 都使用數據查詢集
類名.query.all()
@main.route('/all/') def all(): data = User.query.all() print(data) return render_template('show.html',data=data)
類名.query.filter([類名.屬性名 條件操做符 值])
默認返回全部
#支持連貫操做 @main.route('/filter/') def filter(): # data = User.query.filter() #返回全部 # data = User.query.filter(User.age>20) #查詢年齡大於20的數據 data = User.query.filter(User.age>20,User.age<40) #查詢年齡大於20的數據 and 小於40 print(data) return render_template('show.html',data=data)
類名.query.filter_by(屬性名=值...)
@main.route('/filter_by/') def filter_by(): # data = User.query.filter_by(id=2) # data = User.query.filter_by(id>2) #錯誤寫法 data = User.query.filter_by(id=2,age=27) return render_template('show.html',data=data)
offset(num)
#偏移量取值 @main.route('/offset/') def offset(): data = User.query.filter().offset(2) return render_template('show.html',data=data)
limit(num)
@main.route('/limit/') def limit(): # data = User.query.limit(2) data = User.query.filter(User.age>30).limit(2) return render_template('show.html',data=data)
@main.route('/offsetlimit/') def offsetlimit(): data = User.query.offset(2).limit(2) # limit 2,2 return render_template('show.html',data=data)
@main.route('/order_by/') def order_by(): # data = User.query.order_by(User.age) #升序 data = User.query.order_by(-User.age) #降序 return render_template('show.html',data=data)
@main.route('/first/') def first(): # data = User.query.first() == User.query.get(2) print(data) print(data.id) print(data.username) return '取出第一條數據'
查詢成功返回對象 查詢失敗 返回None
@main.route('/first/') def first(): data = User.query.get(2) return '取出第一條數據'
@main.route('/contains/') def contains(): #username中包含數字7的數據 data = User.query.filter(User.username.contains('7')) return render_template('show.html',data=data)
@main.route('/like/') def like(): #username中包含數字7的數據 # data = User.query.filter(User.username.like('%7%')) # data = User.query.filter(User.username.like('李%')) #以李做爲開頭的 data = User.query.filter(User.username.like('%6')) #以6做爲結尾的數據 return render_template('show.html',data=data)
#startswith endswith @main.route('/startend/') def startend(): # data = User.query.filter(User.username.startswith('李')) data = User.query.filter(User.username.endswith('6')) return render_template('show.html',data=data)
__gt__
__ge__
__lt__
__le__
>
<
>=
<=
==
!=
@main.route('/bjiao/') def bjiao(): # data = User.query.filter(User.age.__gt__(20)) # data = User.query.filter(User.age.__ge__(99)) data = User.query.filter(User.age!=99) return render_template('show.html',data=data)
@main.route('/in/') def myIn(): # data = User.query.filter(User.age.in_([27,12,1,30,40,50])) data = User.query.filter(~User.age.in_([27,12,1,30,40,50])) return render_template('show.html',data=data)
@main.route('/null/') def null(): # data = User.query.filter(User.username == None) # data = User.query.filter(User.username != None) # data = User.query.filter(User.username.is_(None)) data = User.query.filter(User.username.isnot(None)) return render_template('show.html',data=data)
多個條件 用逗號隔開,爲and操做
from sqlalchemy import and_
@main.route('/and/') def myAnd(): # data = User.query.filter(User.age==27,User.id==2) data = User.query.filter(and_(User.age==27,User.id==2)) return render_template('show.html',data=data)
from sqlalchemy import or_
@main.route('/and/') def myAnd(): data = User.query.filter(or_(User.age==27,User.id==2)) data = User.query.filter(and_(User.username.like('%6%')),or_(User.age>=27,User.id==2)) return render_template('show.html',data=data)
from sqlalchemy import not_
@main.route('/and/') def myAnd(): # data = User.query.filter(not_(User.age>27,User.id==1))\ #錯誤寫法只能給一個條件取反 data = User.query.filter(not_(User.age>27)) return render_template('show.html',data=data)
data = User.query.filter(not_(User.age>27)).count()
模塊:
pip install flask-migrate
pip install flask-script
from flask_migrate import Migrate,MigrateCommand from flask_sqlalchemy import SQLalchemy app = Flask(__name__) db = SQLalchemy(app) migrate = Migrate(app,db=db) manager = Manager(app) manager.add_command('db',MigrateCommand)
python manage.py db init
python manage.py db migrate
python manage.py db upgrade
注意
若是當前存在 模型 可是執行建立遷移文件的時候 提示沒有任何改變的時候 須要查看當前的模型類是否有使用(導入)