Как обновить базу данных без явного объявления движка и сеанса в SQLAlchemy - PullRequest
0 голосов
/ 22 октября 2018

Контекст

Использование учебника Flask pocoo.org (ссылка) в качестве отправной точки, я пытаюсь работать с внешней базой данных SQL вместоsqlite3.Обзор документации конфигурации и модели для pocoo здесь и здесь помог мне установить соединение, и запрашиваемые данные отображаются в моем приложении, что хорошо.

Что не работает

Проблема в том, что когда я обновляю запись через представление обновления, она не обновляет базу данных при отправке.Вместо этого запрос страницы загружается без каких-либо ошибок, все еще представляя данные в прежнем состоянии.

То, что я пробовал до сих пор

Я посмотрелдля решения в документации, Google и архивах stackoverflow, но, насколько я могу судить, они предполагают, что приложение подключается к базе данных через объявленный сеанс, связанный с движком.Учебник Pocoo, с другой стороны, явно не объявляет сеанс или не привязывается к движку;вместо этого он регистрирует файл db.py, который инициализирует базу данных, вместе с фабрикой приложений.Соединение настраивается с помощью ключа конфигурации SQLALCHEMY_DATABASE_URI, и модуль sqlalchemy, предположительно, обрабатывает движок и сеанс «за кулисами».Или, по крайней мере, это то, что я понял.Но я явно что-то неправильно понял (или многие вещи).

Я также пытался явно зафиксировать сеанс.Он не выдавал никаких ошибок при отправке, но не обновлял базу данных.

Обобщая вопрос

Как я могу получить свое приложение (представленное файламиниже) обновить базу данных без явного объявления движка и сеанса, что, я думаю, будет значительным отклонением от подхода, описанного в руководстве по Pocoo?

Кстати

Одно случайное различие между моими файлами ниже и теми из учебника заключается в том, что, хотя учебник использует посты в блоге в качестве основного элемента записи, я изменил его на проекты.Но эти два аналогичны в отношении структуры данных.

__ init __. Py

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

def create_app(test_config=None):
    # create and configure the app
    app = Flask(__name__, instance_relative_config=True)
    app.config.setdefault(
        'SQLALCHEMY_DATABASE_URI', '***Omitted for security***'
    )

    if test_config is None:
        # load the instance config, if it exists, when not testing
        app.config.from_pyfile('config.py', silent=True)
    else:
        # load the test config if passed in
        app.config.from_mapping(test_config)

    with app.app_context():
        from . import db
        db.init_app(app)

        from . import summary
        app.register_blueprint(summary.bp)
        app.add_url_rule('/', endpoint='index')

    return app

models.py

from sqlalchemy import Column, Integer, String, ForeignKey, Date
from flaskr.db import get_db

db = get_db()

class projects(db.Model):
    __tablename__ = 'projects'

    project_id = db.Column(db.Integer, primary_key=True)
    project = db.Column(db.String(255), unique=True, nullable=False)
    project_manager = db.Column(db.String(26), unique=False, nullable=True)
    business_benefits = db.Column(db.String(1024), unique=False, nullable=True)

db.py

import click
from flask import current_app, g
from flask.cli import with_appcontext
from flask_sqlalchemy import SQLAlchemy

def get_db():
    if 'db' not in g:
        g.db = SQLAlchemy(current_app)
    return g.db

def init_db():
    db = get_db()

@click.command('init-db')
@with_appcontext
def init_db_command():
    """Clear the existing data and create new tables."""
    init_db()
    click.echo('Initialized the database.')

def init_app(app):
    app.cli.add_command(init_db_command)

summary.py

from flask import (
    Blueprint, flash, g, redirect, render_template, request, session, url_for, current_app
)

from flaskr.db import get_db

with current_app.app_context():
    from flaskr.models import projects

bp = Blueprint('summary', __name__)

@bp.route('/')
def index():
    db = get_db()
    project = projects.query.all()
    return render_template('summary/index.html', projects=project)

@bp.route('/<int:id>/update', methods=('GET', 'POST'))
def update(id):
    db = get_db()
    project = projects.query.filter_by(project_id=id).first()

    if request.method == 'POST':
        project.project_name = request.form['project']
        project.business_benefits = request.form['business_benefits']
        error = None
        db.session.commit()

        if not project:
            error = 'Project name is required.'

        if error is not None:
            flash(error)
        else:
            return redirect(url_for('summary.index', projects=project))

    if request.method == 'GET':
        return render_template('summary/update.html', post=project)
...