数据库ORM操作

1. 数据库ORM操作实现

​ 为了实现ORM方式操作数据库,而不是使用SQL语句,就需要通过安装Flask-SQLAlchemy扩展库来实现。同时通过安装Flask-Migrate扩展库实现数据库更新的跟踪,并实现数据迁移。

pip install Flask-SQLAlchemy
pip install Flask-Migrate

2. 配置sqlite数据库

​ 对于小型应用来说,使用sqlite数据库更为便利,每一个数据库都单独存放在一个文件中。使用sqlite数据库需要在app/config.py配置文件进行相关配置。

# 配置SQLITE数据库信息
BASE_DIR = os.path.abspath(os.path.dirname(__file__))
# 数据库文件存放路径
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(BASE_DIR, '..', 'instance', 'flask.sqlite')
# Flask-SQLAlchemy 是否需要追踪对象的修改并且发送信号。
# 这需要额外的内存, 如果不必要的可以禁用它。
SQLALCHEMY_TRACK_MODIFICATIONS = False

3. 初始化数据库

​ 修改app/__init__.py初始化文件,初始化数据库

......
import os
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate


# 实例化flask_sqlalchemy
db = SQLAlchemy()
# 实例化flask_migrate
migrate = Migrate()


def create_app():
    """应用工厂函数"""
    application = Flask(__name__)
    # 加载config配置文件
    application.config.from_pyfile('config.py', silent=True)

    # 初始化数据库flask_sqlalchemy
    db.init_app(application)
    # 初始化数据库flask_migrate
    import app.models
    migrate.init_app(application, db)
......

4. 创建数据库模型

​ 新建app/models.py文件,创建用户信息的数据库模型。

from app import db


class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    nickname = db.Column(db.String(64), index=True, unique=True)
    email = db.Column(db.String(120), index=True, unique=True)
    posts = db.relationship('Post', backref='author', lazy='dynamic')

    def __init__(self, nickname=None, email=None):
        self.nickname = nickname
        self.email = email

    def __repr__(self):
        """打印类对象时的展示方式"""
        return '<User %r>' % self.nickname

5. 数据库模型初始化

5.1. 迁移目录初始化

​ 通过flask db init命令,初始化数据库模型迁移目录migrations

(venv) D:\Projects\learn\flask-mega-tutorial>flask db init
Creating directory D:\Projects\learn\flask-mega-tutorial\migrations ... done
Creating directory D:\Projects\learn\flask-mega-tutorial\migrations\versions ... done
Generating D:\Projects\learn\flask-mega-tutorial\migrations\alembic.ini ... done
Generating D:\Projects\learn\flask-mega-tutorial\migrations\env.py ... done
Generating D:\Projects\learn\flask-mega-tutorial\migrations\README ... done
Generating D:\Projects\learn\flask-mega-tutorial\migrations\script.py.mako ... done
Please edit configuration/connection/logging settings in 'D:\\Projects\\learn\\flask-mega-tutorial\\migrations\\alembic.ini' before proceeding.

Flask学习笔记-(三)数据库ORM操作

5.2. 迁移文件创建

​ 通过flask db migrate命令,将数据库迁移文件生成到迁移目录versions中,同时也初始化创建了Flask-Migrate扩展库依赖的数据库表。

(venv) D:\Projects\learn\flask-mega-tutorial>flask db migrate
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.autogenerate.compare] Detected added table 'users'
INFO  [alembic.autogenerate.compare] Detected added index 'ix_users_email' on '['email']'
INFO  [alembic.autogenerate.compare] Detected added index 'ix_users_nickname' on '['nickname']'
Generating D:\Projects\learn\flask-mega-tutorial\migrations\versions\3eb9976120ab_.py ... done

Flask学习笔记-(三)数据库ORM操作

5.3. 数据库同步

​ 通过flask db upgrade命令,将数据库迁移文件的变化同步到数据库中。

(venv) D:\Projects\learn\flask-mega-tutorial>flask db upgrade
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade  -> 3eb9976120ab, empty message

Flask学习笔记-(三)数据库ORM操作

6. 新增数据库模型、数据库同步

6.1. 新增数据库模型定义

​ 编辑app/models.py文件,新增posts表的数据库模型定义

from app import db


class User(db.Model):
    __tablename__ = 'users'
    id = db.Column(db.Integer, primary_key=True)
    nickname = db.Column(db.String(64), index=True, unique=True)
    email = db.Column(db.String(120), index=True, unique=True)
    posts = db.relationship('Post', backref='author', lazy='dynamic')

    def __init__(self, nickname=None, email=None):
        self.nickname = nickname
        self.email = email

    def __repr__(self):
        """打印类对象时的展示方式"""
        return '<User %r>' % self.nickname


class Post(db.Model):
    __tablename__ = 'posts'
    id = db.Column(db.Integer, primary_key=True)
    body = db.Column(db.String(140))
    timestamp = db.Column(db.DateTime)
    user_id = db.Column(db.Integer, db.ForeignKey('users.id'))

    def __repr__(self):
        return '<Post %r>'.format(self.body)

6.2. 迁移文件创建

(venv) D:\Projects\learn\flask-mega-tutorial>flask db migrate
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.autogenerate.compare] Detected added table 'posts'
Generating D:\Projects\learn\flask-mega-tutorial\migrations\versions\36458070dda2_.py ... done

6.3. 数据库同步

(venv) D:\Projects\learn\flask-mega-tutorial>flask db upgrade
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade 3eb9976120ab -> 36458070dda2, empty message

Flask学习笔记-(三)数据库ORM操作

7. 数据库操作回退

​ 通过flask db downgrade命令,对已同步的数据库进行回退处理,此操作仅限于数据库同步的回退,但是迁移文件还在。

(venv) D:\Projects\learn\flask-mega-tutorial>flask db downgrade
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.runtime.migration] Running downgrade 36458070dda2 -> 3eb9976120ab, empty message

Flask学习笔记-(三)数据库ORM操作

8. 数据库操作测试

8.1. 数据查询

>>> from app.models import User
>>> User.query.all()
[]

8.2. 数据插入

>>> from app import create_app, db
>>> app = create_app()
>>> app.app_context().push()
>>> with app.app_context():
...     from app.models import User
...     u = User('admin', '[email protected]')
...     db.session.add(u)
...     db.session.commit()
...     db.session.close()
...     users = User.query.all()
...     print(users)
...     
[<User 'admin'>]

Flask学习笔记-(三)数据库ORM操作

8.3. 数据删除

>>> with app.app_context():
...     from app.models import User
...     db.session.delete(User.query.filter(User.nickname == 'admin').one())
...     db.session.commit()
...     db.session.close()
...

Flask学习笔记-(三)数据库ORM操作

相关文章: