flask - Flask_wtf - UnmappedInstanceError:类未映射
问题描述
我正在使用一个不太简单的数据库构建一个相对简单的 Flask 应用程序。我有很多模型来处理和关联数据库中所有需要的信息。
出于某种原因,我收到了标题错误。
我开始认为这与我的数据库模型/关系有什么关系。
因此,模型的实现如下:
from app import db, login
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import UserMixin
import datetime
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
password = db.Column(db.String(128))
def set_password(self, password):
self.password = generate_password_hash(password)
def check_password(self, passwd):
return check_password_hash(self.password, passwd)
def __repr__(self):
return '<User {}>'.format(self.username)
class airFeedVariator(db.Model):
variatorID = db.Column(db.Integer, db.ForeignKey('variator.id',onupdate='RESTRICT',ondelete='RESTRICT'), primary_key=True)
airFeedID = db.Column(db.Integer, db.ForeignKey('air_feed.id',onupdate='RESTRICT',ondelete='RESTRICT'), primary_key=True)
variatorRel = db.relationship('Variator', backref='variators',lazy='joined')
freq = db.Column(db.Integer)
class Variator(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(30))
machineID = db.Column(db.Integer)
baudrate = db.Column(db.Integer)
addedAt = db.Column(db.DateTime, default=datetime.datetime.utcnow) # the current timestamp
class Air_feed(db.Model):
id = db.Column(db.Integer, primary_key=True)
timeOn = db.Column(db.Integer)
timeOff = db.Column(db.Integer)
desc = db.Column(db.String)
digital = db.relationship('Pin_function', backref='analog_or_digital', lazy=True)
airFeedTypeId = db.relationship('Air_feed_type', backref='air_feed_type_id', lazy=True, uselist=False) #This allow the usage for a single element. 1-1 Rel.
#variators = db.relationship('Variator', secondary=airFeedVariator, lazy='subquery',backref=backref('airfeedvariators', lazy=True))
variators = db.relationship('airFeedVariator', lazy='dynamic')
表格如下:
from flask_wtf import FlaskForm
from wtforms import StringField, PasswordField, BooleanField, SubmitField, IntegerField, DateTimeField
from wtforms.validators import ValidationError, DataRequired, Email, EqualTo
from flask_babel import lazy_gettext as _l #compile in runtime only.
#Utilizado para converter directamente os modelos em forms.
#from wtforms_alchemy import ModelForm
from app import models
from wtforms_alchemy import model_form_factory
BaseModelForm = model_form_factory(FlaskForm)
class ModelForm(BaseModelForm):
@classmethod
def get_session(self):
print('Session: ', db.session)
return db.session
class LoginForm(FlaskForm):
username = StringField(_l('Utilizador'), validators=[DataRequired()])
password = PasswordField(_l('Password'), validators=[DataRequired()])
remember_me = BooleanField(_l('Lembrar-me'))
submit = SubmitField(_l('Submeter'))
class RegistrationForm(FlaskForm):
username = StringField('Username', validators=[DataRequired()])
email = StringField('Email', validators=[DataRequired(), Email()])
password = PasswordField('Password', validators=[DataRequired()])
password2 = PasswordField(
'Repetir Password', validators=[DataRequired(), EqualTo('password')])
submit = SubmitField(l_('Registo'))
#Validate on submit check for this. The rise allow to write a message directly on the webpage!
def validate_username(self, username):
user = models.User.query.filter_by(username=username.data).first()
if user is not None:
raise ValidationError(_l('Utilizador já existente!'))
def validate_email(self, email):
user = models.User.query.filter_by(email=email.data).first()
if user is not None:
raise ValidationError(_l('Email já existente!'))
class VariatorForm(FlaskForm):
name = StringField(_l('Nome'), validators=[DataRequired()])
machineID = IntegerField(_l('Identificador'), validators=[DataRequired()])
baudrate = IntegerField(_l('Valocidade Comm'), validators=[DataRequired()])
addedAt = DateTimeField(_l('Preenchimento automatico')) # the current timestamp
def validate_machineID(self, machineID):
user = models.Variator.query.filter_by(machineID=machineID.data).first()
if user is not None:
raise ValidationError(_l('Já existente um variador registado neste endereço!'))
我确实意识到我在其他人身上有一个 FlaskForm 表单和 ModelForm,我只是在测试。
我的问题如下:
File "c:\app\routes.py", line 49, in SaveVariator
db.session.add(var) File "c:\gburner\lib\site-packages\sqlalchemy\orm\scoping.py", line 153, in do
return getattr(self.registry(), name)(*args, **kwargs) File "c:\gburner\lib\site-packages\sqlalchemy\orm\session.py", line 1833, in add
raise exc.UnmappedInstanceError(instance) sqlalchemy.orm.exc.UnmappedInstanceError: Class 'app.forms.VariatorForm' is not mapped
* 添加 Problatic route.py 部分 *
@app.route('/savevariator', methods=['POST'])
def SaveVariator():
var = VariatorForm(request.form)
if var.validate_on_submit():
print('Variator form submit accepted!')
### I was doing this ### Trying to add the FORM to the session!
db.session.add(var)
db.session.commit()
#############################
### INSTEAD I Should be doing this: ######
variator = Variator(name=var.name, machineID=var.machineID, baudrate=var.baudrate)
db.session.add(variator)
db.session.commit()
##############################
resp = jsonify(success=True)
else:
print('Variator form submit NOT accepted!')
resp = jsonify(success=False)
return resp
我认为不需要 html 代码,因为在调用保存数据库信息之前一切正常。
我是否缺少有关数据库中映射关系的某些内容,因为我有 3 个用于多对多关系的表?
任何解决问题的帮助将不胜感激。谢谢你。
* 编辑 * 感谢Joost指出我这个简单但难以实现的点!(我可能应该更频繁地暂停)。
解决方案
问题出在路线部分:
@app.route('/savevariator', methods=['POST'])
def SaveVariator():
var = VariatorForm(request.form)
if var.validate_on_submit():
print('Variator form submit accepted!')
### I was doing this ### Trying to add the FORM to the session!
db.session.add(var)
db.session.commit()
#############################
### INSTEAD I Should be doing this: ######
variator = Variator(name=var.name, machineID=var.machineID, baudrate=var.baudrate)
db.session.add(variator)
db.session.commit()
##############################
resp = jsonify(success=True)
else:
print('Variator form submit NOT accepted!')
resp = jsonify(success=False)
return resp
感谢Joost,我能够理解问题出在哪里。再次感谢!
我意识到这是一个简单的错误,但我找不到有关错误和解决方案的太多信息。但是,如果管理员认为不值得保留,请随时将其删除。
谢谢你。
推荐阅读
- docker - docker run 立即退出?
- reactjs - 将默认坐标放在天蓝色反应地图代码中的位置(Map.js)
- javascript - Bootstrap 的选项卡更改功能在 ReactJS 中不起作用
- python-3.x - 根据python中的日期差异扩展数据框
- react-native - 如何使用 react-native-router-flux 在组件内实现选项卡
- css - 带有 alpha 通道的 hsl 用斜线分隔
- flutter - 定时器不取消颤振
- python - 使用套接字和线程时 conn.recv(1024) 出现模糊错误
- node.js - 如何在 mongoDB 中显示即将到来的时间表?
- docker - Azure DevOps 在部署时替换 docker 映像中 web.config 中的变量