首页 > 解决方案 > Flask-SQLAlchemy sqlite 在 db.session.commit() 上崩溃

问题描述

我有以下代码。我正在尝试使用 SQLAlchemy 将用户数据插入到 sqlite 数据库中,当我在 python 提示符下给出以下命令时它会崩溃。我正在尝试将用户添加到数据库然后一旦我提交我想查询数据库并显示信息以验证它是否已插入数据库。现在我只在提示符下显示它,我还没有开发任何方法来渲染它。

from DIRT import db
db.create_all()
from DIRT import User, Post
user_1 = User(username="John Wick", email="jw@gmail.com", password="password")
user_2 = User(username="John Snow", email="js@gmail.com", password="password")
db.session.add(user_1)
db.session.add(user_2)
db.session.commit()

下面是我的 DIRT.py 代码

from datetime import datetime
from flask import Flask, render_template, url_for, flash, redirect
from flask_sqlalchemy import SQLAlchemy
from MyForms import RegisterForm, LoginForm


app = Flask(__name__)

# creating secret numbers to prevent modified cookie attack, or cross-site attacks
app.config['SECRET_KEY'] = '4b15463cce52d7b99874c9fb2312d580'

# database uri
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///dirt.db'

# database
db = SQLAlchemy(app)


# user model for the sql database
# class User(db.Model):
#   id = db.Column(db.Integer, primary_key=True)
#  username = db.Column(db.String(25), unique=True, nullable=False)
#  email = db.Column(db.String(50), unique=True, nullable=False)
#  image_file = db.Column(db.String(25), nullable=False, default='default.jpg')
#    password = db.Column(db.String(50), nullable=False)
#    posts = db.relationship('Post', backref='author', lazy=True)

#   def __repf__(self):
#       return f"User('{self.username}', '{self.email}', '{self.image_file}')"

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(20), unique=True, nullable=False)
    email = db.Column(db.String(120), unique=True, nullable=False)
    password = db.Column(db.String(60), nullable=False)
    posts = db.relationship('Post', backref='author', lazy=True)

    def __repr__(self):
        return f"User('{self.username}', '{self.email}')"


class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    content = db.Column(db.Text, nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

    def __repr__(self):
        return f"Post('{self.title}', '{self.date_posted}')"


posts = [
    {
        'author': 'Cloud Strife',
        'title': 'Where do we find Aeris..',
        'content': 'So we are trying to find her',
        'date_posted': 'November 12, 2019'

    },
    {
        'author': 'Cecil Paladin',
        'title': 'Where is the crystal sword',
        'content': 'Trying to find the crystal bridge',
        'date_posted': 'July 10, 2019'

    }

]


@app.route("/")
@app.route("/home")
def home():
    return render_template('home.html', posts=posts)


@app.route("/about")
def about():
    return render_template('about.html', title='About')


@app.route("/register", methods=['GET', 'POST'])
def register():
    form = RegisterForm()
    if form.validate_on_submit():
        flash(f'Account created for {form.username.data} successfully!', 'success')
        return redirect(url_for('home'))
    return render_template('register.html', title='Register', form=form)


# @app.route("/login", methods=['GET', 'POST'])
# def login():
#    MyForm = LoginForm()
#   return render_template('login.html', title='Login', form=MyForm)

@app.route("/login", methods=['GET', 'POST'])
def login():
    form = LoginForm()
    if form.validate_on_submit():
        if form.email.data == 'onyxbird@hotmail.com' and form.password.data == 'sandman23':
            flash(f'{form.email.data} has logged in!', 'success')
            return redirect(url_for('home'))
        else:
            flash('Login Unsuccessful. Please check email and password', 'danger')
    return render_template('login.html', title='Login', form=form)


if __name__ == '__main__':
    #   app.run(host='0.0.0.0', port='8080')
    # above is production mode
    app.run(debug=True)

这是我得到的错误:

*db.session.commit()
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "C:\Users\onyxb\PycharmProjects\DIRT\venv\lib\site-packages\sqlalchemy\orm\scoping.py", line 162, in do
    return getattr(self.registry(), name)(*args, **kwargs)
  File "C:\Users\onyxb\PycharmProjects\DIRT\venv\lib\site-packages\sqlalchemy\orm\session.py", line 1027, in commit
    self.transaction.commit()
  File "C:\Users\onyxb\PycharmProjects\DIRT\venv\lib\site-packages\sqlalchemy\orm\session.py", line 492, in commit
    self._assert_active(prepared_ok=True)
  File "C:\Users\onyxb\PycharmProjects\DIRT\venv\lib\site-packages\sqlalchemy\orm\session.py", line 288, in _assert_active
    raise sa_exc.InvalidRequestError(
sqlalchemy.exc.InvalidRequestError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (sqlite3.IntegrityError) NOT NULL constraint failed: user.image_file
[SQL: INSERT INTO user (username, email, password) VALUES (?, ?, ?)]
[parameters: ('John Wick', 'jw@gmail.com', 'password')]
(Background on this error at: http://sqlalche.me/e/gkpj) (Background on this error at: http://sqlalche.me/e/7s2a)*

标签: pythonflasksqlalchemy

解决方案


推荐阅读