[python3.6 flask web学习]Flask操作msql数据库

来源:互联网 发布:简单的单片机设计作品 编辑:程序博客网 时间:2024/06/05 09:06

1.flask-sqlalchemy介绍

sqlalchemy是一个orm框架,简化了数据库的操作,sqlalchemy支持mysql,postgres,sqlite等多种数据库。为了简化sqlalchemy的使用,Flas对sqlalchmey进行了扩展。采用pip命令安装

pip install flask-sqlalchemy
pip install mysqlclient //mysql数据库模块

flask-sqlalchemy连接主流数据的方式如下

MySQL mysql://username:password@hostname/database
Postgres postgresql://username:password@hostname/database
SQLite(Unix) sqlite:////absolute/path/to/database
SQLite(Windows) sqlite:///c:/absolute/path/to/database

flask-sqlalchemy使用的数据库url必须配置到flask的配置对象的SQLALCHEMY_DATABASE_URI。其中还有一个配置项SQLALCHEMY_COMMIT_ON_TEARDOWN,如果配置为True,则每次请求完成后会自动提交。下面是mysql的配置

from flask.ext.sqlalchemy import SQLAlchemyapp = Flask(__name__)app.config['SQLALCHEMY_DATABASE_URI'] = \'mysql://username:password@localhost:3306/python'app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = Truedb = SQLAlchmey(app)

db对象是SQLAlchemy类的势力,表示程序使用的数据库,提供Flask-SQLAlchemy提供的所有功能


2.Flask-SQLAlchemy数据模型和模型关系(一对一,一对多,多对多)

模型为继承SQLAlchemy的model类的对象。下面定义Role和User两个模型

class Role(db.Model):    __tablename__ = 'roles' //表名    id = db.Column(db.Integer, primary_key=True) //primary_key 是否主键    name = db.Column(db.String(64), unique = True) //unique 是否唯一    users = db.relationship('User', backref='role', lazy='dynamic') //一个role对应多个user,User表明这种关系另外一端为User对象,backref表示向Userd对象中添加role属性def __repr__(self):        return '<Role %r>' % self.nameclass User(db.Model):    __tablename__ = 'users'    id = db.Column(id.Integer, primary_key = True)    username = db.Column(db.String(64), unique = True, index = True) //index 索引    role_id=db.Column(db.Integer, db.ForeignKey(roles.id)) //多对一关系中一的一方    def __repr(self):        return "<User %r>" % self.username

Integer,String为SQLAlchemy 支持的列类型,下面是常用的类型列表和说明
Integer int 普通整数,一般是32 位
SmallInteger int 取值范围小的整数,一般是16 位
BigInteger int 或long 不限制精度的整数
Float float 浮点数
Numeric decimal.Decimal 定点数
String str 变长字符串
Text str 变长字符串,对较长或不限长度的字符串做了优化
Unicode unicode 变长Unicode 字符串
UnicodeText unicode 变长Unicode 字符串,对较长或不限长度的字符串做了优化
Boolean bool 布尔值
Date datetime.date 日期
Time datetime.time 时间
DateTime datetime.datetime 日期和时间
Interval datetime.timedelta 时间间隔
Enum str 一组字符串
PickleType 任何Python 对象自动使用Pickle 序列化
LargeBinary str 二进制文件
另外需要注意的是Flask-SQLAlchemy要求所有的模型都必须有主键,名字通常为id


3.Flask-SQLAlchemy增删查改

打开python shell,并且执行创建表

(venv) F:\python\flasky>python hello.py shell>>> from hello import db>>> db.create_all() //创建表

插入数据

>>> from hello import Role, User>>> admin_role = Role(name = 'Admin')>>> user_role = Role(name = 'User')>>> user_john = User(username = 'john', role = admin_role)>>> user_susan = User(username = 'susan', role = user_role)>>> db.session.add_all([admin_role, user_role, user_john, user_susan])>>> db.session.commit()//提交事务

修改数据

修改数据直接也是调用add方法即可,

>>> admin_role.name = 'administrator'>>> db.session.add(admin_role)>>> db.session.commit()


删除数据,调用delete()方法

>>> db.session.delete(user_susan)>>> db.session.commit()

数据查询

>>> Role.query.all() //查询所有数据

可以使用str函数查看原生的sql语句

>>> str(Role.query)'SELECT roles.id AS roles_id, roles.name AS roles_name \nFROM roles'

按条件查询

>>> User.query.filter_by(role=admin_role).all()[<User 'john'>]
>>> Role.query.filter_by(name='User').all()[<Role 'User'>]


多对一的关联查询

>>> user_role = Role.query.filter_by(name='User').first() //按条件查询Role>>> user_role.users.all() //查询关联的users集合[<User 'susan'>]

4.在视图函数中操作数据库

@app.route('/', ['GET', 'POST'])def index():    form = NameForm()    if form.validate_on_submit():        user = User.query.filter_by(username=form.name.data)        if user is None:            user = User(username = form.name.data)            db.session.add(user)            session['kown'] = False //判断是否新用户的标志       else:            session['know'] = True        session['name'] = form.name.data        form.name.data = ''        return redirect(url_for('index'))    return render_template('index.html', form =form, name = session.get('name'), know = session.get('know'), False)


5.集成python shell

上面我们在shell中操作数据库还是比较方便的,但是如果每次关掉shell,又要重新导入db,Role等数据库实例和模型。为了避免这一重复工作,可以利用Flask-Script模块的Shell函数在每次shell启动的自动导入特定对象。

from flask.ext.script import Shelldef make_shell_context()://定义回掉函数,导入特定对象    return dict(app=app, db=db, User=User, Role=Role)manager.add_command("shell", Shell(make=make_shell_context))

现在打开shell之后会自动导入app,db,User,Role这些对象

python hello.py shell


6.使用Flask-Migrate数据迁移

代码一般有诸如svn、git等版本控制工具,可以跟踪代码的变更。Flask-Migrate为数据库提供了这种能力。

当创建好了数据库之后,如果后期需要修改数据库模型,由于Flask-SQLAlchemy只会在数据库表不存在的时候才会创建,因此更新表的唯一方法就是先使用db.drop_all()删除表。可以这样数据也删除了。因此更新表的更好方法就是使用数据迁移框架Flask-Migirate
安装扩展模块

pip install flask-migirate

使用步骤

第一步:hello.py:配置Flask-Migrate

from flask.ext.migrate import Migrate, MigrateCommand#...migirate = Migrate(app, db)manager.add_command('db'. MigrateCommand)
为了导出数据库迁移命令,Flask-Migrate 提供了一个MigrateCommand 类,可附加到Flask-Script 的manager 对象上。在这个例子中,MigrateCommand 类使用db 命令附加。

第二步:初始化迁移仓库

python hello.py db init

第二步:创建迁移脚本

python hello.py db migrate -m 'initial migration'

第三步:使用upgrade或者downgrade把变更应用到数据库

python hello.py db upgrade