Как заставить Flask-SQLAlchemy работать с шаблоном фабрики приложений - PullRequest
0 голосов
/ 02 февраля 2019

Я хочу настроить базу данных sqlite с помощью Flask-SQLAlchemy.Я получаю операционную ошибку (sqlite3.OperationalError) no such table.

Это для веб-приложения, написанного с помощью flask.Я хочу взаимодействовать с базой данных, используя расширение Flask-SQLAlchemy.Я чувствую, что это может быть связано с контекстом приложения, но я не уверен.

Как видите, приложение имеет один «модуль» (подпакет auth).Модуль зарегистрирован в приложении через план.Я определяю модель для класса Researcher в файле models.py подпакета auth.app/__init__.py содержит Фабрику приложений и инициализацию базы данных.Поскольку я просто пытаюсь заставить работать базовую функциональность, только два моих представления определены в app/auth/routes.py.


.
|-- app
|   |-- __init__.py
|   |-- auth
|   |   |-- __init__.py
|   |   |-- __pycache__
|   |   |-- models.py
|   |   `-- routes.py
|   |-- static
|   `-- templates
|-- app.db
|-- config.py
|-- instance
|   `-- config.py
`-- run.py

app / init .py

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 

app / auth / rout.py

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", "Pat_Den@mail.com", "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

app /auth / models.py

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

app / auth / init .py

from flask import Flask, Blueprint

auth = Blueprint("auth", __name__)

import routes
import models

config.py

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'INSERT INTO исследователи (префикс, суффикс,phone, phone_ext, orcid) VALUES (?,?,?,?,?) '] [параметры: (' Доктор ',' Мистер ',' 08611111 ',' +353 ',' 0001 ')] (Фон наэта ошибка в: http://sqlalche.me/e/e3q8)"

enter image description here

Ответы [ 2 ]

0 голосов
/ 02 февраля 2019

В тот момент, когда код выполняет db.create_all(), модели не были импортированы.Их импорт имеет побочный эффект от заполнения некоторых структур данных, которые SQLAlchemy использует за кулисами.Если db.create_all() происходит до того, как SQLAlchemy узнает о моделях, он думает, что ничего не поделаешь.

Попробуйте: В __init__.py удалите with app.appcontext(): db.create_all() и добавьте import models в конец.Затем добавьте команду управления к run.py.Это будет выглядеть примерно так:

app = create_app()

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

Тогда

FLASK_APP=run.py flask createdb

создаст таблицы.

0 голосов
/ 02 февраля 2019

Я не смог воспроизвести ваши проблемы, но это помогло мне.

В папке вашего приложения: python3 -m venv источник venv venv / bin / activip install install flask flask_sqlalchemy pip install-е.колба работает

__init__.py

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 

setup.py

from setuptools import setup

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

auth / __init__.py

from flask import Flask, Blueprint

import auth.routes
import auth.models

auth / models.py

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", "Pat_Den@mail.com", "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

auth / rout.py

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", "Pat_Den@mail.com", "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
...