实验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的概念。