简述
SQLAlchemy是个非常优秀的orm,flask可以根据自己的爱好使用orm,但是既然使用flask,首选当然是flask-sqlalchemy。
安装
pip3 install flask-sqlalchemy
初始化
from flask import Flask,render_template
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@127.0.0.1:3306/flask?charset=utf8'
# 初始化
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(40), unique=True)
mobile = db.Column(db.String(20), unique=True)
password = db.Column(db.String(255))
def __init__(self, username, mobile, password):
self.username = username
self.mobile = mobile
self.password = password
def __repr__(self):
return '<User %r>' % self.username
访问页面的时候报错No module named 'MySQLdb'
解决方法:安装pymysql
pip3 install pymysql
数据对象创建
class Users(db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(40), unique=True)
mobile = db.Column(db.String(20), unique=True)
password = db.Column(db.String(255))
def __init__(self, username, mobile, password):
self.username = username
self.mobile = mobile
self.password = password
def __repr__(self):
return '<User %r>' % self.username
备注:默认情况下Users对象是数据库表users的映射,如果类名与数据库表名不一致,可以通过属性__tablename__=users指定
。
指定表名示例:
class Users(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(40), unique=True)
mobile = db.Column(db.String(20), unique=True)
password = db.Column(db.String(255))
def __init__(self, username, mobile, password):
self.username = username
self.mobile = mobile
self.password = password
def __repr__(self):
return '<User %r>' % self.username
正确使用
先上代码(文件命名为hello.py):
import os
from flask import Flask
from flask_script import Manager
from flask_sqlalchemy import SQLAlchemy
basedir = os.path.abspath(os.path.dirname(__file__))
app = Flask(__name__)
app.config['SECRET_KEY'] = 'hello vilay'
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:12346@127.0.0.1:3306/flask?charset=utf8'
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)
manager = Manager(app)
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64),unique=True)
role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
def __repr__(self):
return '<User %r>' % self.name
class Role(db.Model):
__tablename__ = 'roles'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(64),unique=True)
def __repr__(self):
return '<User %r>' % self.name
users = db.relationship('User',backref='role')
if __name__ == '__main__':
manager.run()
上面代码,引入了两个扩展,Flask-Script和Flask-SQLAlchemy
进入命令行,执行命令
python3 hello.py shell
创建表
输入下面的代码
from hello import db
db.create_all()
数据库表创建成功,如果数据库已经有表了不会创建,换句话说如果你更改了字段那么这招无效。需要先删除数据库表,再创建。先执行db.drop_all()
,再db.create_all()
插入行
也是再命令行执行下面代码
>>> from hello import Role, User
>>> admin_role = Role(name='admin')
>>> mod_role = Role(name='moderator')
>>> user_role = Role(name='user')
>>> user_vilay = User(name='vilay',role=admin_role)
>>> user_city = User(name='city',role=mod_role)
>>> user_dity = User(name='dity',role=user_role)
是不是觉得插入数据库了,我也是这么觉得的。但是并没有插入数据库。
可以执行下面命令试试
>>> print(admin_role.id)
None
这些新建对象的 id 属性并没有明确设定,因为主键是由 Flask-SQLAlchemy 管理的。现在这些对象只存在于 Python 中,还未写入数据库。因此 id 尚未赋值。通过数据库会话管理对数据库所做的改动,在 Flask-SQLAlchemy 中,会话由 db.session 表示。准备把对象写入数据库之前,先要将其添加到会话中,执行下面的命令
>>> db.session.add(admin_role)
>>> db.session.add(mod_role)
>>> db.session.add(user_role)
>>> db.session.add(user_vilay)
>>> db.session.add(user_city)
>>> db.session.add(user_dity)
也可以这样
>>> db.session.add_all([admin_role, mod_role, user_role,user_vilay, user_city, user_dity])
再执行提交命令
>>> db.session.commit()
再去看数据库,数据生成成功了。
修改行
>>> admin_role.name='Administrator'
>>> db.session.add(admin_role)
>>> db.session.commit()
删除行
>>> db.session.delete(mod_role)
>>> db.session.commit()
查询
>>> Role.query.all()
基本操作完成。
每次重启都需要from hello import User,Role
太麻烦了,我们可以这么做
在上面代码中新引入两句
from flask_script import Manager, Shell
# 中间省略
def make_shell_context():
return dict(app=app,db=db,User=User,Role=Role)
manager.add_command('shell',Shell(make_context=make_shell_context))
#后面省略
数据库迁移
示例代码:
from flask_migrate import Migrate, MigrateCommand
# 中间省略
migrate = Migrate(app,db)
manager.add_command('db',MigrateCommand)
#后面省略
执行
python3 hello.py db init #始化数据库,会创建一个migations文件夹
python3 hello.py db migrate -m 'init' #创建迁移历史
python3 hello.py db upgrade # 更新迁移