关于python:如何让Flask-SQLAlchemy使用Application Factory Pattern

How to get Flask-SQLAlchemy to work with the Application Factory Pattern

我想使用flask sqlAlchemy建立一个sqlite数据库。我得到一个操作错误"(sqlite3.operational error)没有这样的表"

这是一个用flask编写的web应用程序。我想使用flask sqlachemy扩展与数据库交互。我觉得这可能与应用程序上下文有关,但我不确定。

如您所见,应用程序有一个模块("auth"模块)。模块通过蓝图注册到应用程序。我在auth子包的models.py类中定义研究员类的模型。app/init.py保存应用程序工厂和数据库初始化。因为我只是想让基本功能正常工作,所以在app/auth/routes.py中只定义了两个视图。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
.
|-- app
|   |-- __init__.py
|   |-- auth
|   |   |-- __init__.py
|   |   |-- __pycache__
|   |   |-- models.py
|   |   `-- routes.py
|   |-- static
|   `-- templates
|-- app.db
|-- config.py
|-- instance
|   `-- config.py
`-- run.py

应用程序/init.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app():
    app = Flask(__name__)
    app.config.from_pyfile("../config.py")

    db.init_app(app)
    with app.app_context():
        db.create_all()

    from app.auth import auth
    app.register_blueprint(auth, url_prefix="/auth/")

    return app

号应用程序/授权/路由.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
from flask import Flask
from app import db
from models import User
from app.auth import auth

@auth.route("/insert")
def insert():
    #r = Reasearcher("Pat","Den","[email protected]","operator","Dr.","Mr","08611111","+353","0001")
    u = User(1,"Elija")
    db.session.add(u)
    db.session.commit()

@auth.route("/query")
def query():
    us = users.query.all()
    s =""
    for u in us:
        s += u.name
    return s

应用程序/授权/型号.py

1
2
3
4
5
6
7
8
9
10
11
12
13
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from app import db

class User(db.Model):
    __tablename__ ="users"

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String)

    def __init__(self,ids, name):
        self.id = ids
        self.name = name

。应用程序/auth/init.py

1
2
3
4
5
6
from flask import Flask, Blueprint

auth = Blueprint("auth", __name__)

import routes
import models

配置PY

1
2
3
4
5
6
7
8
9
10
11
12
13
DEBUG = True

import os
BASE_DIR = os.path.abspath(os.path.dirname(__file__))

SQLALCHEMY_DATABASE_URI ="sqlite:////" + os.path.join(BASE_DIR,"app.db")
DATABASE_CONNECT_OPTIONS = {}
THREADS_PER_PAGE = 2

CSRF_ENABLED     = True

CSRF_SESSION_KEY ="secret"
SECRET_KEY ="secret"

我应该能够请求/auth/query并获取数据库表的内容,但是我得到了错误-"operationalerror:(sqlite3.operationalerror)没有这样的表:研究人员[SQL:U'插入研究人员(前缀、后缀、电话、电话分机或ID)值(?"??????[参数:('dr.'、'mr'、'08611111'、'+353'、'0001')](此错误的背景:http://sqlalche.me/e/e3q8)

enter image description here


在代码执行db.create_all()的时候,模型还没有被导入。导入它们有填充SQLAlchemy在后台使用的某些数据结构的副作用。如果db.create_all()发生在sqlacalchemy了解模型之前,它认为没有什么可做的。

试试这个:在__init__.py中,去掉with app.appcontext(): db.create_all()并在底部加上import models。然后向run.py添加一个管理命令。它看起来像

1
2
3
4
5
app = create_app()

@app.cli.command()
def createdb():
    db.create_all()

然后

1
FLASK_APP=run.py flask createdb

将创建表。


我没能复制你的问题,但这对我很有效。

在你的应用文件夹中:Python3-m静脉震源venv/bin/激活PIP安装烧瓶管道安装-E。烧瓶运行

__init__.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
from flask import Flask, render_template
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app():
    app = Flask(__name__)
    app.config.from_pyfile("../config.py")

    db.init_app(app)
    with app.app_context():
        db.create_all()

        import auth
        app.register_blueprint(auth.routes.auth, url_prefix="/auth/")

        return app

设置.py

1
2
3
4
5
6
7
8
9
from setuptools import setup

setup(
    name='yourapplication',
    include_package_data=True,
    install_requires=[
        'flask',
        ],
    )

授权/__init__.py

1
2
3
4
from flask import Flask, Blueprint

import auth.routes
import auth.models

授权/型号.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from flask import Flask, Blueprint
from app import db
from auth.models import Researcher

auth = Blueprint("auth", __name__)

@auth.route("/insert")
def insert():
    #r = Reasearcher("Pat","Den","[email protected]","operator","Dr.","Mr","08611111","+353","0001")
    r = Researcher("Dr.","Mr","08611111","+353","0001")
    db.session.add(r)
    db.session.commit()

    @auth.route("/query")
    def query():
        rs = Researcher.query.all()
        s =""
        for r in rs:
            s += r.prefix +"" + r.phone
            return s

授权/路由.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
from flask import Flask, Blueprint
from app import db
from auth.models import Researcher

auth = Blueprint("auth", __name__)

@auth.route("/insert")
def insert():
    #r = Reasearcher("Pat","Den","[email protected]","operator","Dr.","Mr","08611111","+353","0001")
    r = Researcher("Dr.","Mr","08611111","+353","0001")
    db.session.add(r)
    db.session.commit()

    @auth.route("/query")
    def query():
        rs = Researcher.query.all()
        s =""
        for r in rs:
            s += r.prefix +"" + r.phone
            return s