在这个教程中,我们选择了SQLite作为数据库管理系统(DBMS)。SQLite是一种关系型数据库管理系统(RDBMS),它基于文件,不需要单独启动数据库服务器。SQLite适合在开发时使用,或者在数据库操作简单、访问量低的程序中使用。

SQLite具有以下优点:

  1. 简单易用:SQLite的设置和配置非常简单,无需复杂的服务器安装和配置过程。
  2. 轻量级:SQLite数据库以单个文件的形式存储在磁盘上,占用空间小且资源消耗较少。
  3. 无服务器:与其他关系型数据库管理系统相比,SQLite不需要独立运行的数据库服务器,可以直接与应用程序集成。
  4. 跨平台:SQLite可在多个操作系统上运行,包括Windows、Mac和Linux等。

需要注意的是,SQLite适用于小型应用程序或原型开发,如果您的应用程序需要处理大量数据或高并发访问,可能需要考虑更高级的数据库管理系统,如MySQL或PostgreSQL。

在接下来的教程中,我们将使用Flask-SQLAlchemy扩展与SQLite数据库进行交互,以简化数据库操作过程。

使用SQLAlchemy操作数据库

为了简化数据库操作,我们将使用SQLAlchemy,它是一个Python数据库工具(ORM,即对象关系映射)。借助SQLAlchemy,您可以通过定义Python类来表示数据库中的表(类属性表示表中的字段/列),通过对这个类进行各种操作来代替编写SQL语句。我们将这个类称为模型类,其中的属性被称为字段。

Flask有许多第三方扩展,这些扩展可以简化与第三方库的集成。下面我们将使用一个名为Flask-SQLAlchemy的扩展来集成SQLAlchemy。

首先安装它:

(env) $ pip install flask-sqlalchemy==2.5.1 sqlalchemy==1.4.47

提示:Flask-SQLAlchemy 3.x / SQLAlchemy 2.x 版本有一些重大变化。在此处,我们固定安装了2.5.1和1.4.47版本。在更新的教程中,将删除这里的版本限制。

大多数扩展都需要执行一个"初始化"操作。您需要导入扩展类,实例化它并传入Flask应用程序实例:

from flask_sqlalchemy import SQLAlchemy  # 导入扩展类

app = Flask(__name__)

db = SQLAlchemy(app)  # 初始化扩展,传入Flask应用程序实例 app

现在,您已经成功初始化了Flask-SQLAlchemy扩展。

使用模型类定义数据库表

在Python Shell中执行以下代码:

(env) $ flask shell
>>> from app import db
>>> db.create_all()

这将创建一个名为data.db的SQLite数据库文件,并根据模型类创建对应的表。你可以在文件管理器中查看到这个数据库文件。请注意,数据库文件不应该提交到版本控制系统中,因此我们在.gitignore文件中添加了对应的规则。

如果你对模型类进行了更改,需要重新生成表结构,可以使用以下代码:

>>> db.drop_all()
>>> db.create_all()

这会删除所有的表并重新创建。但请注意,这将清空所有数据。如果你需要在保留数据的情况下修改表结构,你可以使用数据库迁移工具,如Flask-Migrate扩展。

为了方便使用,我们还创建了一个自定义命令initdb,可以通过命令行初始化数据库:

import click

@app.cli.command()
@click.option('--drop', is_flag=True, help='Create after drop.')
def initdb(drop):
    """Initialize the database."""
    if drop:
        db.drop_all()
    db.create_all()
    click.echo('Initialized database.')

你可以使用以下命令初始化数据库:

(env) $ flask initdb

如果你想先删除表再重新创建,可以使用--drop选项:

(env) $ flask initdb --drop

以上是创建数据库模型的步骤。

数据库增删改查

接下来我们将学习如何使用数据库模型类进行数据库操作,包括创建、读取、更新和删除记录。

创建记录:

from app import User, Movie

user = User(name='Grey Li')
m1 = Movie(title='Leon', year='1994')
m2 = Movie(title='Mahjong', year='1996')

db.session.add(user)
db.session.add(m1)
db.session.add(m2)
db.session.commit()

以上代码演示了如何创建UserMovie的记录,并使用db.session.add()将记录添加到数据库会话中,最后通过db.session.commit()提交会话以将记录保存到数据库。

读取记录:

from app import Movie

movie = Movie.query.first()  # 获取第一条记录
print(movie.title)  # 输出记录的title字段值

movies = Movie.query.all()  # 获取所有记录
for movie in movies:
    print(movie.title, movie.year)  # 输出记录的title和year字段值

count = Movie.query.count()  # 获取记录数量
print(count)

movie = Movie.query.get(1)  # 根据主键获取指定记录
print(movie)

movie = Movie.query.filter_by(title='Mahjong').first()  # 根据title字段过滤获取第一条记录
print(movie)

以上代码演示了如何使用查询方法从数据库中读取记录。我们使用Movie.query来创建查询对象,并通过调用查询方法(如first()all()count()等)获取相应的记录或记录数量。还可以使用过滤方法(如filter_by()filter()等)对记录进行过滤。通过调用记录的属性,我们可以访问记录的字段值。

更新记录:

movie = Movie.query.get(2)  # 获取要更新的记录
movie.title = 'WALL-E'  # 更新记录的title字段值
movie.year = '2008'
db.session.commit()  # 提交改动

以上代码演示了如何更新数据库中的记录。我们首先使用查询方法获取要更新的记录,然后直接对记录的属性赋予新的值,最后通过db.session.commit()提交改动。

删除记录:

movie = Movie.query.get(1)  # 获取要删除的记录
db.session.delete(movie)  # 删除记录
db.session.commit()  # 提交改动

以上代码演示了如何删除数据库中的记录。我们首先使用查询方法获取要删除的记录,然后使用db.session.delete()方法将记录删除,最后通过db.session.commit()提交改动。

这些是常见的数据库操作示例,你可以根据需要进行相应的操作。注意,在每次修改数据库后,都需要调用db.session.commit()来提交改动,否则修改不会生效。

在程序中操作数据库可以通过视图函数进行。以下是在Watchlist中进行实际数据库操作的示例。

在主页视图中读取数据库记录:

@app.route('/')
def index():
    user = User.query.first()  # 读取用户记录
    movies = Movie.query.all()  # 读取所有电影记录
    return render_template('index.html', user=user, movies=movies)

index视图函数中,我们使用User.query.first()来获取用户记录,并使用Movie.query.all()获取所有电影记录。然后将usermovies作为参数传递给模板index.html

index.html模板中,原来的name变量被user实例取代,因此需要将模板中的两处name变量更新为user.name属性:

<h1>{{ user.name }}'s Watchlist</h1>
...
<p>Welcome, {{ user.name }}!</p>

生成虚拟数据:

我们可以编写一个自定义命令函数,用于向数据库添加虚拟数据。以下是用于生成虚拟数据的命令函数:

import click

@app.cli.command()
def forge():
    """Generate fake data."""
    db.create_all()

    name = 'Grey Li'
    movies = [
        {'title': 'My Neighbor Totoro', 'year': '1988'},
        {'title': 'Dead Poets Society', 'year': '1989'},
        {'title': 'A Perfect World', 'year': '1993'},
        {'title': 'Leon', 'year': '1994'},
        {'title': 'Mahjong', 'year': '1996'},
        {'title': 'Swallowtail Butterfly', 'year': '1996'},
        {'title': 'King of Comedy', 'year': '1999'},
        {'title': 'Devils on the Doorstep', 'year': '1999'},
        {'title': 'WALL-E', 'year': '2008'},
        {'title': 'The Pork of Music', 'year': '2012'},
    ]

    user = User(name=name)
    db.session.add(user)
    for m in movies:
        movie = Movie(title=m['title'], year=m['year'])
        db.session.add(movie)

    db.session.commit()
    click.echo('Done.')

现在,通过运行flask forge命令,可以将虚拟数据添加到数据库中。

请注意,对于每次修改数据库操作后,都需要调用db.session.commit()来提交更改,以使更改生效。

标签: flask教程, flask技术, flask学习, flask学习教程, flask下载, flask开发, flask入门教程, flask进阶教程, flask高级教程, flask面试题, flask笔试题, flask编程思想