フォームを送信しようとすると、sqlalchemy.exc.InterfaceErrorが表示されます

2020年06月03日に質問されました。  ·  閲覧回数 14回  ·  ソース

Adrian Kwamena Ackon picture
2020年06月03日

デバッガーとして表示されるエラー:

sqlalchemy.exc.InterfaceError: (sqlite3.InterfaceError) Error binding parameter 2 - probably unsupported type.
[SQL: INSERT INTO meals (name_of_meal, number_of_minutes_to_prepare, diet_id, ingredients, procedure, number_of_people_to_serve, user_id) VALUES (?, ?, ?, ?, ?, ?, ?)]
[parameters: ('Oil Rice', '13', [], 'Shall be added', 'Shall be added', '2', 1)]
(Background on this error at: http://sqlalche.me/e/rvf5)

当初、モデルとフォームは整数値を使用していましたが、これらが機能していなかったため、文字列値を取得するためにすべてに切り替えました。

以下はモデルクラスです

class Meal(db.Model):
    __tablename__ = 'meals'
    id = db.Column(db.Integer(), primary_key = True)
    name_of_meal = db.Column(db.String(50))
    number_of_minutes_to_prepare = db.Column(db.String(10))
    diet_id = db.Column(db.Integer(), db.ForeignKey('diets.id'))
    ingredients = db.Column(db.String(5000))
    procedure = db.Column(db.String(5000))
    number_of_people_to_serve = db.Column(db.String())
    user_id = db.Column(db.Integer(),db.ForeignKey('users.id'))

    def __init__(self, name_of_meal,number_of_minutes_to_prepare, diet_id, ingredients, procedure, number_of_people_to_serve, user_id):
        self.name_of_meal = name_of_meal
        self.number_of_minutes_to_prepare = number_of_minutes_to_prepare
        self.diet_id = diet_id
        self.ingredients = ingredients
        self.procedure = procedure
        # self.picture = picture
        self.number_of_people_to_serve = number_of_people_to_serve
        self.user_id = user_id

    def __repr__(self):
        return f"Name of meal: {self.name_of_meal} by Cook/User: {self.user_id}"

以下は、この食事モデルが外部キーを拡張するユーザークラスです。

class User(db.Model,UserMixin):
    __tablename__ = 'users'
    id = db.Column(db.Integer(), primary_key=True)
    email = db.Column(db.String(100), unique = True)
    name = db.Column(db.String(64))
    username = db.Column(db.String(20), unique = True)
    password = db.Column(db.String(128))
    nationality_id = db.Column(db.Integer(),db.ForeignKey('nationality.id'))
    about_user = db.Column(db.String(1000), default = "")
    # profile_picture = db.Column(db.LargeBinary())
    number_of_recipes = db.Column(db.Integer(), default = 0)
    created_on = db.Column(db.DateTime(), default = datetime.utcnow)
    updated_on = db.Column(db.DateTime(), default = datetime.utcnow, onupdate = datetime.utcnow)
    comments = db.relationship('Comment', backref = 'comments', lazy='dynamic')
    meals = db.relationship('Meal', backref='meal', lazy='dynamic')


    def __init__(self, email, name, password, username, nationality_id):
        self.email = email
        self.name = name
        self.password = generate_password_hash(password)
        self.username = username
        self.nationality_id = nationality_id

以下は、食事モデルが拡張される食事モデルです。

class Diet(db.Model):
    __tablename__ = 'diets'
    id = db.Column(db.Integer(), primary_key = True)
    diet_category = db.Column(db.String(100), unique = True)
    diet_description = db.Column(db.String(500))
    recipes = db.relationship('Meal', backref = 'meals', lazy = 'dynamic')

    def __init__(self, diet_category, diet_description):
        self.diet_category = diet_category
        self.diet_description = diet_description

    def __repr__(self):
        return f"{self.id}. {self.diet_category}: {self.diet_description}"

テンプレートで使用されるフォームクラス:

class AddMeal(FlaskForm):
    name_of_meal = StringField("Recipe Name/ Meal Name", validators=[DataRequired()])
    number_of_minutes_to_prepare = StringField("Approximate number of minutes to prepare", validators=[DataRequired()], render_kw={"placeholder": "(N.B.) 60 mins = 1 hour"})
    diet_meal = SelectMultipleField("Special diet meal for any type of person?", choices = [], coerce = int, default = (0, "Diets in which this meal can be taken"))
    ingredients = TextAreaField("Ingredients Needed", validators=[DataRequired()])
    procedure = TextAreaField("Procedure", validators=[DataRequired()], render_kw={"placeholder": "Please be as specific as possible \n Kindly give a precise description on how to make the meal"})
    number_of_people_to_serve = StringField("Number of people it can serve", validators=[DataRequired()])
    submit = SubmitField("ADD RECIPE")

ビュールート:

@app.route('/add-recipe', methods=['GET', 'POST'])
@login_required
def add_recipe():
    form = AddMeal()
    form.diet_meal.choices = [(diet.id, diet.diet_category)for diet in Diet.query.all()]
    if form.validate_on_submit():
        name_of_meal = form.name_of_meal.data
        number_of_minutes_to_prepare = form.number_of_minutes_to_prepare.data
        diet_meal = form.diet_meal.data
        ingredients = form.ingredients.data
        procedure = form.procedure.data
        number_of_people_to_serve = form.number_of_people_to_serve.data
        user_id = current_user.id
        new_recipe = Meal(name_of_meal,
         number_of_minutes_to_prepare, diet_meal,
          ingredients, procedure, number_of_people_to_serve, user_id)
        db.session.add(new_recipe)
        db.session.commit()
        flash("Recipe has been successfully added")
        return redirect(url_for('dashboard'))
    return render_template('admin/new_recipe.html', form = form)

回答

Adrian Kwamena Ackon picture
2020年06月08日
0

クラッシュの原因はSelectMultipleField行であることに気づきました。それを削除した後、プログラムは正常に実行されました。