美文网首页
Flask-SQLAlchemy 代码模块化

Flask-SQLAlchemy 代码模块化

作者: Stone0823 | 来源:发表于2018-12-13 20:45 被阅读29次

本文主要介绍把 Flask-SQLAlchemy 代码进行模块化划分的时候,需要注意的问题。

如果把 Flask-SQLAlchemy 的代码全部放在一个文件中,示例代码如下:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import os

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DB_URI')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

db = SQLAlchemy(app)

class Users(db.Model):
    id = db.Column(db.Integer, nullable=False, primary_key=True)
    name = db.Column(db.String(20), nullable=False)

    def __repr__(self):
        return '<User %r>' % self.name

if __name__ == '__main__':
    db.create_all()

我们的目的是创建数据库和数据库表。以上代码有如下几个要点:

  • Flask-SQLAlchemy 的数据库连接 uri 写在 app.config 配置中,这是一个 dict 类型的结构,KEY 为 SQLALCHEMY_DATABASE_URI。Python 3.2 之后,不能用 MysqlDb 模块连接数据库,要使用 PyMysql 模块。 SQLALCHEMY_DATABASE_URI 的写法为:
mysql+pymysql://username:password@server_name:3306/database_name?charset=utf8
  • create_all() 方法不能在 MySQL 数据库自动创建数据库,需要手工创建。在网上搜索,没有找到自动创建的解决方法

  • create_all() 方法在创建表的时候,如果数据库表已经存在,则模型的改动不会作用于实际的表,要先调用 drop_all() 方法然后再调用 create_all() 方法进行覆盖

现在我们假设考虑工程的文件结构模块化,工程文件结构如下:

flask_sqlalchemy_test /
    app /
        __init__.py
        models.py
    create_table.py

首先在 app/models.py 中编写如下代码:

from flask_sqlalchemy import SQLAlchemy

db = SQLAlchemy()

class Users(db.Model):
    id = db.Column(db.Integer, nullable=False, primary_key=True)
    name = db.Column(db.String(16), nullable=False)

    def __repr__(self):
        return '<User %r>' % self.name

然后在 app/__init__.py 中编写如下代码:

from flask import Flask
import os
from app.models import db

def create_app():
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DB_URI')
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True

    db.init_app(app)

    return app

说明:在 models.py 中定义 db: db = SQLAlchemy() ,没有初始化 app,而是在 create_app() 函数中,通过 db.init_app() 方法初始化 app。

然后在 create_table.py 中调用代码创建数据库表:

from app.models import db
from app import create_app

app = create_app()

if __name__ == '__main__':
    db.create_all()

我们试着运行一下,Oops,出现了如下错误:

RuntimeError: application not registered on db instance and no application bound to current context

出现错误的原因是 Flask 允许多个 app 同时存在,所以有 application context 的概念,db.init_app() 的时候,并不清楚要初始化哪一个 app,我们需要在 init_app() 在这个语句之前,要加上一行代码,像下面这样:

db.app=app #<------------<<
db.init_app(app)

参考

相关文章

网友评论

      本文标题:Flask-SQLAlchemy 代码模块化

      本文链接:https://www.haomeiwen.com/subject/esqbhqtx.html