Flask-SQLAlchemy: как условно вставить или обновить строку

мое приложение использует комбинацию колбы, колбы-SQLAlchemy, колбы-WTF и Jinja2.

в его текущем воплощении у меня есть таблица настроек. В таблице будет только одна запись с одним полем. Изначально таблица содержит ноль записей.

чего я хочу добиться-это:

  • учитывая, что в БД нет записей, покажите пустую форму, готовую для ввода пользователем
  • учитывая, что запись существует, покажите запись и
  • если пользователь изменяет значение, а затем обновляет rec в db.

вот мой код:

models.py

class Provider(db.Model):
    id = db.Column(db.Integer, primary_key = True)
    rssfeed = db.Column(db.String(120), unique = True)

    def __init__(self, rssfeed):
        self.rssfeed = rssfeed

    def __repr__(self):
        return '<NZBMatrix feed url %r>' % self.rssfeed

forms.py

class SettingsForm(Form):
    rssfeed = TextField('rssfed', validators= [Required()])

views.py

    @app.route('/settings', methods=["GET","POST"])
    def settings():
    """ show settings """
        provider = Provider.query.get(1)
        form = SettingsForm(obj=provider)
        print provider

        if request.method == "POST" and form.validate():
            if Provider.query.get(1) is None:
                provider = Provider(rssfeed=form.rssfeed.data)
                form.populate_obj(provider)
                db.session.add(provider)
                db.session.commit()
                flash("Settings added")

        return render_template("settings.html", form=form)

как он стоит этот код создает запись, если он не существует, но rssfeed столбец пуст.

как я могу изменить этот код, чтобы он был INSERT если запись не существует и UPDATE если ли?

2 ответов


Как только ваша форма будет проверена и т. д.,

добавить новую запись:

new_provider = Provider(form.rssfeed.data)
db.session.add(new_provider)
db.session.commit()

обновить существующую запись:

existing_provider = Provider.query.get(1) # or whatever
# update the rssfeed column
existing_provider.rssfeed = form.rssfeed.data
db.session.commit()

трюк в обновлении заключается в том, что вам просто нужно изменить конкретное поле и сделать фиксацию. отдых осуществляется сеансом БД. Я думаю, вы используете функцию слияния, которая теперь устарела в SQLAlchemy.


мне удалось решить проблему, сделав эти изменения в view.py файл:

@app.route('/settings', methods=["GET","POST"])
def settings():
    """ show settings """
    provider = Provider.query.get(1)
    form = SettingsForm(request.form,obj=provider)

    if request.method == "POST" and form.validate():
        if provider:
            provider.rssfeed = form.rssfeed.data
            db.session.merge(provider)
            db.session.commit()
            flash("Settings changed")
            return redirect(url_for("index"))
        else:
            provider = Provider(form.rssfeed.data)
            db.session.add(provider)
            db.session.commit()
            flash("Settings added")
            return redirect(url_for("index"))
    return render_template("settings.html", form=form)