实验3、Flask数据库操作-如何使用Flask与数据库
1. 实验内容
数据库的使用对于可交互的Web应用程序是极其重要的,本节我们主要学习如何与各种主要数据库进行连接和使用,以及ORM的使用
2. 实验要点
- 掌握Flask对于各种主要数据库的连接方法
- 掌握ORM的使用规则
3.实验环境
- Centos 7.9
4. 工作目录
本实验的工作目录为: /experiment
Flask数据库教程
在本教程中,我们可以讨论比较的数据库之间的区别。此外,我们讨论了Flask-MongoEngine,Flask-SQLAlchemy和Flask MongoAlchemy。这两个ORM(即对象关系映射器)非常流行。
底层的ORM将对象(数据库模型)透明地转换为数据库命令或SQL语句。
下面列出了使用ORM的好处:
- 开发人员可以使用对象而不是表和SQL。
- 使用迁移来跟踪数据库更新。
- 它减少了开发成本和时间。
- 它克服了特定于数据库的SQL差异。
使用ORM后,程序员不必编写复杂的SQL查询和命令即可执行基本SQL命令。
启动数据库
打开配置文件,注意以下提到的值。Flask-Appbuilder通过这些值获取连接字符串上的数据库详细信息。
MONGODB_SETTINGS = {
'DB': 'mydb'
}
ORM的数据库管理的所有低级功能都包装在Flask Click命令下,我们可以在命令行上使用flask fab –help
看到这些命令。
(venv) [root@bogon exampleApp]# flask fab –help
Usage: flask fab [OPTIONS] COMMAND [ARGS]...
FAB flask group commands
Options:
--help Show this message and exit.
Commands:
babel-compile Babel, Compiles all translations
babel-extract Babel, Extracts and updates all messages marked for...
collect-static Copies flask-appbuilder static files to your projects...
create-addon Create a Skeleton AddOn (needs internet connection to...
create-admin Creates an admin user
create-app Create a Skeleton application (needs internet...
create-db Create all your database objects (SQLAlchemy...
create-permissions Creates all permissions and add them to the ADMIN...
create-user Create a user
list-users List all users on the database
list-views List all registered views
reset-password Resets a user's password
security-cleanup Cleanup unused permissions from views and roles.
security-converge Converges security deletes...
version Flask-AppBuilder package version
(venv) [root@bogon exampleApp]#
在本节中,我们将学习如何使用ORM而不是使用原始SQL脚本来在Flask中使用数据库。
·MongoDB·是基于关系的非关系数据库。我们已经使用当前的Flask教程示例应用程序对其进行了配置。
使用下面提供的命令在本地计算机上启动MongoDB服务
mongod --dbpath /var/lib/mongodb --logpath /var/log/mongodb/mongod.log --fork
之后输入mongo
使用数据库
创建数据库内容
我们讨论了可以与MongoDB和Flask一起使用的两个著名的ORM。
使用数据库设计器,我们创建了两个名为专辑和歌曲的表,并定义了专辑和歌曲之间的一对多关系。下面给出的是描绘它的图像。
现在,让我们创建第一个MongoEngine数据库模型。
在app目录下创建或编辑文件models.py
并添加以下代码。
from mongoengine import Document
from mongoengine import DateTimeField, StringField, ReferenceField, ListField, IntField
class Album(Document):
name = StringField(unique=True, required=True, max_lenth=100)
def __str__(self):
return self.name
class Song(Document):
title = StringField(max_lenth=200, required=True, unique=True)
rating = IntField(default=0, max_lenth=1) # 1 to 9
album = ReferenceField(Album)
def __str__(self):
return self.title
我们已经创建了两个名为Album和Song的MongoEngine模型。这些模型对应于MongoDB中的相应文档。
Album具有一个字符串类型的字段,并具有一些约束。
- Album名称是唯一的。
- Album名称不能为空。
- Album名称最多可以包含一百个字符。
类似地,文档Song具有标题,评级字段和指向另一个文档Album的引用字段。保存该文件并使用这两个模型创建数据。转到项目的根目录,并使用flask shell
命令访问Python shell中的flask应用程序(注意:要在项目文件夹下执行命令)。
使用以下语句访问MongoEngine模型并创建示例数据,如下所示。
flask shell
>>> from app.models import Album, Song
>>> album1 = Album(name="Album1")
>>> album1.save()
>>> song1 = Song(title="Song1", rating=9, album=album1)
>>> song1.save()
现在,让我们使用Mongo客户端访问数据库,并查看是否由于上述语句而保存了数据。在上面的代码中,我们首先导入Album和Song,然后使用所需的参数值创建它们的对象。
这里的参数是模型中定义的字段名称,我们将数据作为这些参数的值来提及。一旦对象创建成功,我们将在各个对象上调用save方法将文档保存在数据库中。
使用mongo命令访问MongoDB。使用mongo客户端连接到服务器后,请使用以下命令。
show dbs
use mydb
show collections
db.album.findOne()
db.song.findOne()
如果您使用过Django,那么您将意识到MongoEngine的工作原理与Django的内置ORM非常相似。在上一个输出中,当我们查询Song时,请注意Album字段中另一个文档的引用。
现在,让我们创建另一个Album,并对现有的Song文档进行更新。
from app.models import Album, Song
album2 = Album(name='Album2')
album2.save()
songs_q = Song.objects(title='Song1') # query the database
songs_q.count()
song1 = songs_q[0]
song1.album = album2 # update the album field
song1.save()
我们导入两个模型,即Album和Song。然后创建一个名为album2的新文档。在数据库中查询Song使用其标题获取Song。然后,我们使用查询结果的数组索引访问该对象,使用赋值运算符进行更新,并保存更新后的文档。
现在,让我们再次使用Mongo客户端来检查存储的集合。
db.album.find().pretty()
db.song.find().pretty()
在上述的第二个查询的输出中,请注意Song1文档的更新Album
现在,让我们删除Album和Song集合中的文档。使用下面的代码删除记录。在Flask shell使用下面提到的命令删除文档并确认删除。
song1.delete()
songs_q = Song.objects(title ='Song1')
songs_q.count()
我们在song1上使用delete方法从Song集中删除文档。我们可以使用Flask Shell执行所有基本的CRUD操作。
视图化数据库内容
此外,我们可以使用flask_appbuilder的ModelView类将数据库模型显示为视图。
创建基于模型的视图,如下面的代码所示,加入到views.py文件中。
from app.models import Album, Song
from flask_appbuilder.models.mongoengine.interface import MongoEngineInterface
class SongsView(ModelView):
datamodel = MongoEngineInterface(Song)
class AlbumView(ModelView):
datamodel = MongoEngineInterface(Album)
我们首先导入数据库模型,以及ModelView和MongoEngineInterface。然后,我们将ModelView子类化,并将特定的MongoEngineInterface实例分配给视图的数据模型属性。
现在,让我们使用以下菜单在同一类别下添加SongsView和AlbumView。
appbuilder.add_view(AlbumView, "Album View", category="Model Views")
appbuilder.add_view(SongsView, "Song View", category="Model Views")
要访问应用程序上的那些视图,请访问IP:8080/
,使用管理员凭据登录到应用程序,然后执行以下步骤以了解基于默认数据库模型的视图。
与上述步骤相似,您可以使用这些视图执行所有CRUD操作。因此,让我们使用“Song查看”子菜单创建一首歌曲,如下图所示。请注意,如何在下拉列表中显示相关数据库模型的参考字段。尝试创建更多Album和Song。
您可以使用MongoAlchemy进一步探索相同的概念。另一个易于使用的,类似的ORM,用于使用Python轻松访问和操作MongoDB数据库。
请在检查https://pythonhosted.org/Flask-MongoAlchemy/ MongoAlchemy的文档。但是,我们建议先通过下面的部分对Flask-SQLAlchemy进行基本的了解。
Flask SQLite or MySQL
Flask Sqlite
在本节中,我们将相同的SQLAlchemy应用程序重新定位为后端引擎。因此我们需要新建一个新的flask-appbuilder项目。Flask可以使用SQLite和MySQL作为后端数据库。我们建议您将SQLAlchemy用作这些关系数据库的ORM(在创建项目的数据库引擎选择SQLAlchemy)。
或通过以下方式修改原程序使用SQLAlchemy
在项目的根目录中打开config.py并删除MongoDB的连接字符串。使用Flask SQLite或Flask MySQL的连接字符串更新config.py。
# The SQLAlchemy connection string.
SQLALCHEMY_DATABASE_URI = "sqlite:///" + os.path.join(basedir, "app.db")
# SQLALCHEMY_DATABASE_URI = 'mysql://myapp@localhost/myapp'
现在打开app / __ init__.py
文件注释掉与MongoEngine有关的import,并如下所示导入SQLALCHEMY。
#from flask_appbuilder.security.mongoengine.manager import SecurityManager
from flask_appbuilder import AppBuilder, SQLA
#from flask_mongoengine import MongoEngine
# other lines of code
#db = MongoEngine(app)
db = SQLA(app)
#appbuilder = AppBuilder(app, security_manager_class=SecurityManager)
appbuilder = AppBuilder(app, db.session)
使用以下代码更新models.py并删除与MongoEngine相关的代码。
from flask_appbuilder import Model
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
class Album(Model):
__tablename__ = 'album'
id = Column(Integer, primary_key=True)
name = Column(String(100), unique=True)
def __repr__(self):
return self.name
class Song(Model):
__tablename__ = 'song'
id = Column(Integer, primary_key=True)
title = Column(String(200), unique=True)
rating = Column(Integer, unique=True)
album_id = Column(Integer(), ForeignKey("album.id"))
album = relationship("Album")
def __repr__(self):
return self.title
views.py
修改为
from flask_appbuilder.models.sqla.interface import SQLAInterface
class SongsView(ModelView):
datamodel = SQLAInterface(Song)
class AlbumsView(ModelView):
datamodel = SQLAInterface(Album)
appbuilder.add_view(AlbumsView, "Album View", category="Model View")
appbuilder.add_view(SongsView, "Song View", category="Model View")
在程序根目录输入flask fab create-db
创建数据库程序,在根目录会生成一个app.db
的数据库文件
成功后我们就替换了原数据库内容,这是我们需要输入flask fab create-admin
重新创建账户
修改成功并启动服务器后,我们就能够看到与之前相同的界面
至此,我们的应用程序将像在MongoDB上一样工作。像前面几节一样,使用所有CRUD操作对其进行测试。
Flask迁移
在应用程序的早期开发过程中,对数据库的架构进行了许多更改。对开发时间造成相当大开销的开发人员需要经常进行这些更改。在类似的情况下,Flask-Migrate插件非常有用。
安装Flask-Migrate(安装过程已完成,无需再次操作)
pip install flask-migrate
成功安装后,将添加db
子命令。通过使用下面提到的代码,检查是否添加成功。
flask db --help
首先,我们需要创建一个迁移对象,在app / __ init__.py
下加入:
from flask_migrate import Migrate
migrate = Migrate(app, db)
之后在根目录输入:
flask db init
与上述命令相似,有些命令可用于创建迁移并使用upgrade命令应用它们。必要时,我们将在后续教程中将这些迁移命令用作工作流的一部分。
常见问题
Q:Flask使用哪个数据库?
A:Flask支持SQLAlchemy支持的所有数据库,SQLAlchemy是Python的数据库工具包,并且是ORM(对象关系映射器)。我们可以从PyPI安装Flask-SQLAlchemy以与SQLAlchemy一起使用。Flask-Alchemy是一个Flask插件,除了安装外,它需要最少的配置。开发人员与Flask-SQLAlchemy一起使用的一些流行数据库是SQLite,PostgreSQL,MySQL等。Flask还具有诸如Flask-MongoEngine,Flask-MongoAlchemy,Flask-CouchDB等插件,以与基于NoSQL文档的数据库(如MongoDB和CouchDB)一起使用。
Q:如何在Flask中创建数据库?
A:在Flask中创建数据库通常取决于相应的Flask插件所遵循的模式。几乎所有插件都基于项目中Flask配置中定义的数据库连接设置来创建数据库。如果不使用插件的话,也可以编写自己的方法在Flask中创建数据库。
import sqlite3
from flask import g # g and current_app object
current_app.config['DATABASE'] = 'MYDB' # Name of the database
def get_db():
'''A method to get the database connection'''
if 'db' not in g:
g.db = sqlite3.connect(
current_app.config['DATABASE'],
detect_types=sqlite3.PARSE_DECLTYPES
)
g.db.row_factory = sqlite3.Row
return g.db
def close_db(e=None):
'''A method to close the database connection'''
db = g.pop('db', None)
if db is not None:
db.close()
Q:如何在Flask中显示数据库中的数据?
A:在Flask中,开发人员使用各种对象关系映射器,也称为ORM。这些ORM通常具有使用查询属性从定义的数据库模型读取数据的API,以访问数据库。使用Flask模板显示存储在Python数据结构中的查询结果。但是,在测试数据库模型时,结果也可以打印在Flask Shell中的控制台上。
实验总结
在本教程中,我们介绍了与使用相同项目布局连接到不同数据库有关的概念。我们摆脱了在代码内部编写原始SQL查询的范例。
以模型形式编写表格的方法使我们更加敏捷。我们还介绍了将数据库信息存储为迁移的概念。迁移进一步增加了我们开发流程的灵活性。
到目前为止,我们已经研究了由Flask应用程序构建器自动生成的原型。在本系列的下一个教程中,我们将进一步采取步骤,并讨论其他Flask样板以及使用Flask BluePrint的概念。
实验3、Flask数据库操作-如何使用Flask与数据库的更多相关文章
- [python]用Python进行SQLite数据库操作
用Python进行SQLite数据库操作 1.导入Python SQLITE数据库模块 Python2.5之后,内置了SQLite3,成为了内置模块,这给我们省了安装的功夫,只需导入即可~ ]: u ...
- 使用JdbcTemplate简化JDBC操作 实现数据库操作
使用Spring JDBC框架方遍简单的完成JDBC操作,满足性能的需求且灵活性高. Spring JDBC框架由4个部分组成,即core.datasource.object.support. org ...
- Django模型-数据库操作
前言 前边记录的URLconf和Django模板全都是介绍页面展示的东西,也就是表现层的内容.由于Python先天具备简单而强大的数据库查询执行方法,Django 非常适合开发数据库驱动网站. 这篇开 ...
- 设计模式 - 单例模式mysql数据库操作类
待续... index.php 调用方法: <?php header('Content-Type:text/html; charset=utf8'); require 'instance.php ...
- iOS学习笔记(十五)——数据库操作(SQLite)
SQLite (http://www.sqlite.org/docs.html) 是一个轻量级的关系数据库.SQLite最初的设计目标是用于嵌入式系统,它占用资源非常少,在嵌入式设备中,只需要几百K的 ...
- ThinkPhp框架的数据库操作(查询)
TP框架有一套自己的数据库操作的代码,包括数据库的增.删.改.查.本文主要讲解TP框架的数据库查询操作. 找到入口文件的控制器: 我这里的入口文件是Show文件夹下的控制器. 打开Login控制器. ...
- MySQL数据库操作类(PHP实现,支持连贯操作)
<?php /** * Author: suvan * CreateTime: 2018/2/27 * description: 数据库操作类(仅对接MySQL数据库,主要利用MySQLi函数) ...
- 雷林鹏分享:CodeIgniter常用的数据库操作类
在 CodeIgniter 中,使用数据库是非常频繁的事情.你可以使用框架自带的数据库类,就能便捷地进行数据库操作. 初始化数据库类 依据你的数据库配置载入并初始化数据库类: $this->lo ...
- PhoneGap 数据库操作
1,openDatabase phonegap官方文档中已经很清楚的标明,如果使用一个数据库首先要用window对象进行创建: var dbShell = window.openDatabase(na ...
随机推荐
- canvas绘制虚线图表
最近有读者加我微信咨询这个问题,如下图所示: 要实现的效果如下: 其实难度不大,但是考虑一些人员对于canvas不熟悉,还是简单的介绍下. 其实该图表,就是一个圆圈外面在套一个圆弧的效果, 主要的难点 ...
- php 获取某数组中出现次数最多的值(重复最多的值)与出现的次数
1.$arr = array(7,7,8,9,10,10,10); $arr = array_count_values($arr); // 统计数组中所有值出现的次数 arsort($arr); ...
- UIautomator2框架快速入门App自动化测试
01.APP测试框架比较 常见的APP测试框架 APP测试框架 02.UIAutomator2简介 简介 UIAutomator2是一个可以使用Python对Android设备进行UI自动化的库. ...
- ImageIo.read 返回null
一.问题描述 今天收到一个bug就是imageio读取图片会返回null,具体如下 但是其他的图片就没有问题 二.问题分析 结合百度发现这张图片原本的后缀并非是jpg,使用notpard++打开就可以 ...
- 面试题:ArrayList、LinkedList、Vector三者的异同?
面试题:ArrayList.LinkedList.Vector三者的异同? 同:三个类都是实现了List接口(Collection的子接口之一),存储数据的特点相同:存储有序的.可重复的数据不同: * ...
- class的大小
3个问题: sizeof一个空类是多大?为什么?编译器为什么这么做? 在这个类中添加一个virtual函数后再sizeof,这时是多大?为什么? 将这个类再virtual继承一个其它的空类,这是多大? ...
- 转: inline关键字使用
1.inline用在函数声明时,还是函数定义时?还是两边都加? 首先,内联函数声明和定义最好在同一个文件中,其它的情况没有实用上的意义. 只要在同一个文件中,声明和定义至少其一加"inlin ...
- Java项目中每一个类都可以有一个main方法
Java项目中每一个类都可以有一个main方法,但只有一个main方法会被执行,其他main方法可以对类进行单元测试. public class StaticTest { public static ...
- 『动善时』JMeter基础 — 14、使用JMeter发送Post请求
目录 1.Post请求参数类型说明 2.用于演示的项目说明 3.发送Post请求示例 (1)测试计划内包含的元件 (2)请求参数类型为x-www-form-urlencoded 4.请求参数form- ...
- 有哪些适用于律师事务所的CRM系统?
中国的经济发展和政治稳定给律师行业带来了巨大的空间.而互联网的发展也让律师事务所遍地开花.如何在大大小小的律所中脱颖而出,是每个律所都迫切需要解决的问题.为了让您的律师事务所在激烈的竞争中脱颖而出,今 ...