错误消息:接口错误:<不可打印的接口错误对象>

use*_*560 5 python flask flask-sqlalchemy

将两个表链接在一起并尝试创建一个包含外键的表单。

sqlalchemy.exc.InterfaceError

InterfaceError: 不可打印的 InterfaceError 对象

数据库链接完成为:

class Client(db.Model):
__tablename__ = 'Client'
..
stand_id = db.Column(db.String(10), index = True, unique = True)
stands = db.relationship('Stand', backref= 'Stand', lazy='select')


def __init__(self,client_name,contact_number,contact_name,contact_email,stand_id):
    self.client_name = client_name
    self.contact_number = contact_number
    self.contact_email = contact_email
    self.contact_name = contact_name
    self.stand_id = stand_id

 class Stand(db.Model):
__tablename__ = 'Stand'
..
stand_number = db.Column(db.String(10), db.ForeignKey('Client.stand_id' )) 

def __repr__(self):
    return '<Stand %r>' % (self.stand_id)


def __init__(self, stand_name,items, quantity,install_date, 
derig_date,comments,last_update, stand_number):
 self.stand_name = stand_name
 self.items = items
 self.quantity = quantity 
 self.install_date = install_date
 self.derig_date =  derig_date
 self.comments = comments
 self.last_update = last_update
 self.stand_number = stand_number
Run Code Online (Sandbox Code Playgroud)

形式为

class StandForm(Form): 
stand_name =  TextField('stand_name', validators = [Required()]) 
items = TextAreaField('items', validators = [Required()])
quantity = TextAreaField('quantity', validators = [Required()])
install_date = TextField('install_date',validators = [Required()])
derig_date = TextField('derig_date', validators = [Required()])
comments = TextField('comments', validators = [Required()])
last_update = TextField('last_update', validators = [Required()])
stand_number = QuerySelectField(query_factory=lambda: Client.query.all())
Run Code Online (Sandbox Code Playgroud)

并查看为

@app.route('/newstand', methods = ['GET','POST'])
def newstand(): 
 form = StandForm()
 if form.validate(): 
    stand = Stand(
     request.form['stand_name'], request.form['items'], request.form['quantity'], 
     request.form['install_date'],request.form['derig_date'], request.form['comments'], 
     request.form['last_update'], request.form['stand_number'])
    form.populate_obj(stand) 
    db.session.add(stand)
    db.session.commit() 
    return render_template('liststands.html',
         stand = stand,
          form=form) 
 else:
    flash("Your form contained errors")
 return render_template('newstand.html', form = form
Run Code Online (Sandbox Code Playgroud)

我认为我写的功能不太正确,有什么意见/帮助吗?

Jer*_*lai 2

我刚刚遇到了同样的错误,看起来可能是类似的问题。 QuerySelectField返回完整的对象,而不仅仅是 ID。对于上面的例子:

重命名表单字段以反映其包含的内容:

class StandForm(Form):
  ...
  stand = QuerySelectField(query_factory=lambda: Client.query.all())
Run Code Online (Sandbox Code Playgroud)

并在视图中构造对象时使用 ID:

@app.route('/newstand', methods = ['GET','POST'])
def newstand(): 
  form = StandForm()
  if form.validate(): 
    stand = Stand(
      request.form['stand_name'], request.form['items'], request.form['quantity'], 
      request.form['install_date'],request.form['derig_date'], request.form['comments'], 
      request.form['last_update'], request.form['stand'].stand_id)
    ...
Run Code Online (Sandbox Code Playgroud)

另外,上面的示例既显式地使用Stand表单内容构造对象,又通过调用form.populate_obj,这可能是多余的(它将再次填充对象上的所有相同字段),因此可以删除其中之一。

如果form.populate_obj自动尊重外键(我认为它确实如此,尽管我还没有尝试过),那么您可以将视图代码简化为:

@app.route('/newstand', methods = ['GET','POST'])
def newstand(): 
  form = StandForm()
  if form.validate(): 
    stand = Stand()
    form.populate_obj(stand)
    ...
Run Code Online (Sandbox Code Playgroud)