我有一个模型:
class Contact(db.Model):
__tablename__ = 'contact'
contactid = db.Column(db.BigInteger, primary_key=True, server_default=db.text("nextval('contact_contactid_seq'::regclass)"))
firstname = db.Column(db.Text)
lastname = db.Column(db.Text)
和一个表单
class ContactForm(FlaskForm):
contactid = HiddenField('contactid')
firstname = StringField('First Name', validators=[Optional()], filters = [lambda x: x or None])
lastname = StringField('Last Name', validators=[Optional()], filters = [lambda x: x or None])
submit = SubmitField('Save')
我使用类似于下面的代码使用上述模型和表单
在数据库中插入和更新记录@blueprint.route('/create', methods=['GET', 'POST'])
def create():
form = ContactForm()
if form.validate_on_submit():
r = Contact()
form.populate_obj(r)
db.session.add(r)
db.session.commit()
flash("saved new record", "success")
return root()
return render_template('contact/create.html', form=form)
@blueprint.route('/edit/<id>', methods=['GET', 'POST'])
def edit(id: int):
r = Contact.query.get_or_404(id)
form = ContactForm(obj=r)
if form.validate_on_submit():
form.populate_obj(r)
db.session.commit()
flash("updated record", "success")
return redirect(url_for('blueprint.root'))
return render_template('contact/edit.html', form=form)
SQLAlchemy生成的SQL如下:
INSERT INTO contact (contactid, firstname, lastname) VALUES (%(contactid)s, %(firstname)s, %(lastname)s)
UPDATE contact set contactid=%(contactid)s, firstname=%(firstname)s, lastname=%(lastname)s WHERE contactid = %(contactid)s
我想让它这样做:
INSERT INTO contact (firstname, lastname) VALUES (%(firstname)s, %(lastname)s)
SELECT last_contactid_somehow
UPDATE contact set firstname=%(firstname)s, lastname=%(lastname)s WHERE contactid = %(contactid)s
我做错了什么?
我想要一个解决方案SqlAlchemy:
- 处理自动递增的主键而不将其插入插入语句
- 没有在update语句 中设置主键。
我正在使用Postgres
我认为第一个问题将通过设置autoincrement=True来解决
class Contact(db.Model):
__tablename__ = 'contact'
contactid = db.Column(db.BigInteger, primary_key=True, autoincrement=True, server_default=db.text("nextval('contact_contactid_seq'::regclass)"))
...
第二个问题实际上是正常工作的,因为你这样定义了表单类。
此外,您想要的查询和SQLAlchemy生成的查询是相同的,因为where子句中的契约和set子句中的契约是相同的。
但是,如果您想更改查询,请更改模型对象的值。
r = Contact.query.get_or_404(id)
form = ContactForm(obj=r)
if form.validate_on_submit():
r.firstname = form.firstname.data
r.lastname = form.lastname.data
db.session.commit()
...