Контекст
Использование учебника 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)