软件测试精进之路数据库百人计划

Flask操作数据库的笔记

2018-10-25  本文已影响88人  cynthia猫

首先,选用的是Flask-SQLAlchemy,这个插件为流行的SQLAlchemy包做了一层封装以便在Flask中调用更方便,类似SQLAlchemy这样的包叫做Object Relational Mapper,简称ORM。 ORM允许应用程序使用高级实体(如类,对象和方法)而不是表和SQL来管理数据库。 ORM的工作就是将高级操作转换成数据库命令。

SQLAlchemy不只是某一款数据库软件的ORM,而是支持包含MySQLPostgreSQLSQLite在内的很多数据库软件。简直是太强大了,你可以在开发的时候使用简单易用且无需另起服务的SQLite,需要部署应用到生产服务器上时,则选用更健壮的MySQL或PostgreSQL服务,并且不需要修改应用代码。

所以我们不必写SQL语句,就可以对数据库进行操作。

新建数据库表,以及关系

class Project(db.Model):
    __tablename__ = 'project'
    id = db.Column(db.Integer(), primary_key=True)
    user_id = db.Column(db.Integer(), nullable=True)
    name = db.Column(db.String(), nullable=True, unique=True)
    host = db.Column(db.String(), nullable=True)
    host_two = db.Column(db.String)
    host_three = db.Column(db.String)
    host_four = db.Column(db.String)
    principal = db.Column(db.String(), nullable=True)
    variables = db.Column(db.String())
    headers = db.Column(db.String())
    created_time = db.Column(db.DateTime, index=True, default=datetime.datetime.utcnow)
    modules = db.relationship('Module', backref='project', lazy='dynamic')
    scenes = db.relationship('Scene', backref='project', lazy='dynamic')

这段代码,第一行是表名,接下来是该表的字段定义。
注意,这里最后两行的 modules ,scenes是使用db.relationship()定义的,它是关系的高级视图,不在数据库图表中。

primary_key是主键。如果需要使用外键,可以这样定义:

project_id = db.Column(db.Integer, db.ForeignKey('project.id'))

创建数据库迁移存储库

Alembic是Flask-Migrate使用的迁移框架,它以一种不需要重新创建数据库的方式进行数据库结构的变更。

flask db init

运行迁移初始化命令之后,你会发现一个名为migrations的新目录。该目录中包含一个名为versions的子目录以及若干文件。从现在起,这些文件就是你项目的一部分了,应该添加到代码版本管理中去。

注意: flask命令依赖于FLASK_APP环境变量来知道Flask应用入口在哪里。 因此需要设置FLASK_APP = xxx.py。否则的话你就要在对应目录下键入xxx.py取代上面命令中的的flask。

问题记录

那么当我在一个开源项目下使用这个命令,迁移数据库到mysql下的时候,出现了下面这个报错:

_mysql_exceptions.OperationalError: (1071, 'Specified key was too long; max key length is 3072 bytes')

而我的索引里面最长的也只是string(1024)而已,小于3072呀,百思不得其解,后来用了网上的方法,把数据库的编码从utf8mb4改为utf8,然后再运行命令,就好了。虽然不知道为什么,总算是解决了这个问题。

运行了这个命令后,就看到数据库表结构已经建立起来了。

包含映射到数据库模型的表的迁移存储库生成后,是时候创建第一次数据库迁移了。

flask db migrate

生成自动迁移

这部分,基于上面提到的那个开源项目,我运行了命令之后,命令行输出是这样的:

python3 xxx.py db migrate
INFO  [alembic.runtime.migration] Context impl MySQLImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.autogenerate.compare] Detected removed index 'ix_apscheduler_jobs_next_run_time' on 'apscheduler_jobs'
INFO  [alembic.autogenerate.compare] Detected removed table 'apscheduler_jobs'
  Generating /mypath/versions/4b05a8a8e2e5_.py ... done

打开数据库看看,好像也没有什么变化嘛。这是因为:
flask db migrate命令不会对数据库进行任何更改,只会生成迁移脚本。 要将更改应用到数据库,必须使用flask db upgrade命令。继续运行:

python3 xxx.py db upgrade
INFO  [alembic.runtime.migration] Context impl MySQLImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade  -> 4b05a8a8e2e5, empty message

命令运行成功。不过看起来这个好像没有什么改动,所以不需要升级。需要升级的话,在上面能看出来的。

好了,通过上面的学习和实践,大概清楚了如何创建表,以及如何迁移数据库。

上一篇下一篇

猜你喜欢

热点阅读