无法使用 Flask 和 Flask-WTF 将行添加到 SQLite 数据库

Unable to add row to SQLite database using Flask and Flask-WTF

我被这个问题困了好一阵子了。我正在尝试向我的 SQLite 数据库添加一行,其中包含来自已提交表单的数据。但是,似乎没有数据被添加到我的数据库中。奇怪的是,当我 运行 手动将数据添加到数据库的函数(详见下文)时,一切正常。 :/ 任何帮助将不胜感激!

下面有四个代码部分,注册表单的创建、flask 路由函数、数据库插入方法,最后是表单的 HTML。

我使用 Flask-WTF 创建我的 SignupForm 如下,

from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, SubmitField
from wtforms.validators import DataRequired, Email, Length

class SignupForm(FlaskForm):
    username = StringField("Username", validators=[DataRequired("Username required!")])
    first_name = StringField("First Name", validators=[DataRequired("First name required!")])
    last_name = StringField("Last Name", validators=[DataRequired("Last name required!")])
    email = StringField("E-Mail", validators=[DataRequired("E-mail required!"), Email("Please enter a valid e-mail!")])
    password = PasswordField("Password", validators=[DataRequired("Password required!"), Length(min=5, message=("Password must be at least 5 characters."))])
    submit = SubmitField("Sign up!")

接下来是我的路由文件中的 signup() 函数。

from flask import Flask, render_template, request, session, redirect, url_for, flash
from forms import SignupForm 
import database_methods

app = Flask(__name__)
app.secret_key = "development key"

@app.route('/signup', methods=["GET", "POST"])
def signup():
    """ Signs a user up for an account so that they may log in """
    form = SignupForm()

    if request.method == 'POST':
        if not form.validate(): # ensure that a user enters all fields correctly
            return render_template('signup.html', form=form)
        else:
            username = form.username.data
            first_name = form.first_name.data
            last_name = form.last_name.data
            email = form.email.data
            password = form.password.data
            database_methods.insert_row_in_db(username, first_name, last_name, email, password)

            return "All right! Signed up!"

    elif request.method == 'GET':
        return render_template('signup.html', form=form)

最后,我们有了将用户输入的数据插入表单的实际方法。

import sqlite3
import os
from werkzeug.security import generate_password_hash
from uuid import uuid4

BASE_DIR = os.path.dirname(os.path.abspath(__file__))
DB_PATH = os.path.join(BASE_DIR, "chat.sqlite")


def insert_row_in_db(username, firstname, lastname, email, password):
    """ Creates a row in chat.sqlite's users table """
    uid = uuid4().hex
    pwd_hash = generate_password_hash(password)
    login_time = set_lastlogin(uid)
    row_data = (uid, username, firstname, lastname, email, pwd_hash, login_time, True)

    with sqlite3.connect(DB_PATH) as conn:
        c = conn.cursor()
        c.execute('''INSERT INTO users (uid, username, firstname, lastname, email, passwordhash, 
                  lastlogin, loggedin) VALUES (?, ?, ?, ?, ?, ?, ?, ?);''', row_data)

如果HTML文件需要参考,这里有。

{% extends "layout.html" %}

{% block content %}

<main>
    <div>
         <h2>Create an Account</h2>

         <form method="POST" action="/signup">
             {{ form.hidden_tag() }}

             <div>
                {{ form.username.label }}

                {% if form.username.errors %}
                    {% for error in form.username.errors %}
                        <p> {{ error }}</p>
                    {% endfor %}
                {% endif %}

                {{ form.username }}
            </div>

            <div>
                {{ form.first_name.label }}

                {% if form.first_name.errors %}
                    {% for error in form.first_name.errors %}
                        <p> {{ error }}</p>
                    {% endfor %}
                {% endif %}

                {{ form.first_name }}
            </div>

            <div>
                {{ form.last_name.label }}

                {% if form.last_name.errors %}
                    {% for error in form.last_name.errors %}
                        <p> {{ error }}</p>
                    {% endfor %}
                {% endif %}

                {{ form.last_name }}
            </div>

            <div>
                {{ form.email.label }}

                {% if form.email.errors %}
                    {% for error in form.email.errors %}
                        <p> {{ error }}</p>
                    {% endfor %}
                {% endif %}

                {{ form.email }}
            </div>

            <div>
                {{ form.password.label }}

                {% if form.password.errors %}
                    {% for error in form.password.errors %}
                        <p> {{ error }}</p>
                    {% endfor %}
                {% endif %}

                {{ form.password }}
            </div>

            {{ form.submit(class="btn btn-primary") }}
        </form>
    </div>
</main>

{% endblock content %}

我已经在谷歌上搜索了几个小时,并且尝试了很多方法都无济于事。如果您能提供任何帮助,我们将不胜感激!

提前致谢! :)

为什么不在查询后调用commit方法呢?在 Flask 文档中 http://flask.pocoo.org/docs/0.12/patterns/sqlite3/#initial-schemas,它在这样查询后提交。

def init_db():
    with app.app_context():
        db = get_db()
        with app.open_resource('schema.sql', mode='r') as f:
            db.cursor().executescript(f.read())
        db.commit()

希望对您有所帮助。

我正在使用 Docker,之前从未使用过。事实证明,docker 正在创建一个与我在 PyCharm 中使用的数据库不同的数据库。我的代码确实有效,只是将它添加到与我期望的不同的数据库中。