如何在不使用SQLAlchemy明确声明引擎和会话的情况下更新数据库

时间:2018-10-22 16:01:41

标签: python flask sqlalchemy flask-sqlalchemy

上下文

以pocoo.org Flask教程(link)作为起点,我正在尝试使用外部SQL数据库而不是sqlite3。关于pocoo herehere的配置和模型文档概述帮助我建立了连接,并且查询的数据正在我的应用程序中呈现,这很好。

什么不起作用

问题在于,当我通过更新视图更新记录时,它不会在提交时更新数据库。取而代之的是,页面请求将加载而不会引发任何错误,同时仍以以前的状态表示数据。

到目前为止我尝试过的事情

我已经在文档,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)

0 个答案:

没有答案