title: Filter sqlalchemy table update with Marshmallow schema
body: <p>I'm developing an api in Flask, using Marshmallow for serialization/deserialization/validation and SQLAlchemy as my ORM.</p>
  
  <p>In my update functions I would like to restrict the fields that can be updated e.g. I don't want users to be able to change their email at the moment.</p>
  
  <p>To achieve this I have set up a schema (UserSchema) with its fields restricted by a tuple (UserSchemaTypes.UPDATE_FIELDS).The tuple does not include email.</p>
  
  <p>The problem I am having is that email is a required field for User rows in my database.</p>
  
  <p>So when I create a User model object using the schema (users_schema.load(user_json) ) an illegal object is added to the sqlalchemy session.</p>
  
  <pre><code>#schema to validate the posted fields against  
  users_schema = UserSchema(only=UserSchemaTypes.UPDATE_FIELDS)
  #attempt to deserialize the posted json to a User model object using the schema
  user_data = users_schema.load(user_json)
  if not user_data.errors:#update data passed validation
     user_update_obj = user_data.data 
     User.update(user_id,vars(user_update_obj))
  </code></pre>
  
  <p>In my update function itself I then have to remove this illegal object from the session via db.session.expunge_all() as if I do not I receive an OperationalError.</p>
  
  <pre><code>@staticmethod    
  def update(p_id,data):
      db.session.expunge_all()#hack I want to remove
      user = User.query.get(p_id)
      for k, v in data.iteritems():
          setattr(user, k, v)
      db.session.commit()
  </code></pre>
  
  <p>OperationalError received when db.session.expunge_all() is removed:</p>
  
  <pre><code>OperationalError: (raised as a result of Query-invoked autoflush; consider        
  using a session.no_autoflush block if this flush is occurring prematurely) 
  (_mysql_exceptions.OperationalError) (1048, &amp;quot;Column 'email' cannot be   null&amp;quot;) [SQL: u'INSERT INTO user (email, password, active, phone, current_login_at, last_login_at, current_login_ip, last_login_ip, login_count) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)'] [parameters: (None, None, 1, '0444', None, None, None, None, None)]
  </code></pre>
  
  <p>Is there a better/cleaner way of doing this?</p>