title: Flask_wtf - UnmappedInstanceError: Class is not mapped
body: <p>I'm building a relatively simple Flask application with a not so simple database. I've a lot of models to handle and relate all the needed information in the DB.</p>
  
  <p>For some reason I'm getting the title error.</p>
  
  <p>I'm starting to think is some how related with my DB models/relationships.</p>
  
  <p>So, the implementation of the models goes as the follow:</p>
  
  <pre><code>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 '&lt;User {}&gt;'.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')
  </code></pre>
  
  <p>And the forms goes as:</p>
  
  <pre><code>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!'))
  </code></pre>
  
  <p>I do realize that I have a FlaskForm form and ModelForm on the others, I was just testing.</p>
  
  <p>My problem is the following:</p>
  
  <pre><code> 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
  </code></pre>
  
  <p><strong>* Added Problatic route.py part *</strong></p>
  
  <pre><code>@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
  </code></pre>
  
  <hr>
  
  <p>I think html code would not be necessary since everything works fine until the moment where the call to save information on database happens.</p>
  
  <p>Am I missing something regarding the mapping relationship in database because I have 3 tables for a many to many relationship?</p>
  
  <p>Any help solve the problem would greatly appreciated.
  Thank you.</p>
  
  <p><strong>* EDIT *</strong>
  Thanks to <a href="https://stackoverflow.com/users/9335964/joost">Joost</a> for point me this simple yet difficult to realize point! (I probably should pause more often).</p>