0
votes

I'm completely stuck with the following error when submitting form data form into a mysql database, very grateful for any clues

I get this error:

"sqlalchemy.orm.exc.FlushError FlushError: Instance has a NULL identity key. If this is an auto-generated value, check that the database table allows generation of new primary key values, and that the mapped Column object is configured to expect these generated values. Ensure also that this flush() is not occurring at an inappropriate time, such aswithin a load() event."

the code is:

from flask import Flask, request,redirect,render_template,flash
from wtforms import Form, TextField, BooleanField
from wtforms.validators import Required
from flask.ext.sqlalchemy import SQLAlchemy

app = Flask(__name__)
db = SQLAlchemy(app)

app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:@127.0.0.1/Jungle'

class Sighting(db.Model):
    __tablename__ = 'Animals'
    animal_name = db.Column(db.String, primary_key = True)
    animal_type = db.Column(db.String)
    scary = db.Column(db.String)

class LoginForm(Form):
    animal_name = TextField('Animal')
    animal_type = TextField('Type')
    scary = BooleanField('Scary')

@app.route('/login',methods = ['GET','POST'])
def login():
    form = LoginForm()    
    if request.method == 'POST':
        newanimal = Sighting(animal_name=form.animal_name.data,animal_type=form.animal_type.data,scary=form.scary.data)
        db.session.add(newanimal)
        db.session.commit()
        return redirect('/thanks')
    elif request.method == 'GET':
        return render_template('login.html', form = form)

@app.route('/thanks',methods= ['GET'])
def thanks():
    return render_template('thanks.html')

if __name__ == '__main__':
  app.run(debug=True)

If I run something like this in the above code it works and successfully commits into the database:

@app.route('/submit',methods =['GET'])
def submit():
    newanimal = Sighting(animal_name='frog',animal_type='amphibian', scary='No')
    db.session.add(newanimal)
    db.session.commit()
    return render_template('thanks.html')

So it seems to be something to do with the form data. The MySQL table is:

CREATE TABLE `Animals` (
  `animal_name` varchar(100) DEFAULT NULL,
  `animal_type` varchar(100) DEFAULT NULL,
  `scary` varchar(100) DEFAULT NULL,
  `id` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`),
  UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8

The database table seems to auto-increment even when one of the failed submissions happens - when you put in a row manually that works its id is a few higher than than the previous one. There's also one row in the table with every field a null.

many thanks in advance!!

(forgive the odd naming schema - its adapted from a tutorial)

sqlalchemy.orm.exc.FlushError
FlushError: Instance <Sighting at 0x10c6552d0> has a NULL identity key.  If this is an auto-generated value, check that the database table allows generation of new primary key values, and that the mapped Column object is configured to expect these generated values.  Ensure also that this flush() is not occurring at an inappropriate time, such aswithin a load() event.

Traceback (most recent call last)
File "/Library/Python/2.7/site-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/Library/Python/2.7/site-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/Library/Python/2.7/site-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/Library/Python/2.7/site-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/Library/Python/2.7/site-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/Library/Python/2.7/site-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/Library/Python/2.7/site-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/Library/Python/2.7/site-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/Users/tomhalloran/TomDev/FlaskSkint/learnv3.py", line 29, in login
db.session.commit()
File "/Library/Python/2.7/site-packages/sqlalchemy/orm/scoping.py", line 149, in do
return getattr(self.registry(), name)(*args, **kwargs)
File "/Library/Python/2.7/site-packages/sqlalchemy/orm/session.py", line 765, in commit
self.transaction.commit()
File "/Library/Python/2.7/site-packages/sqlalchemy/orm/session.py", line 370, in commit
self._prepare_impl()
File "/Library/Python/2.7/site-packages/sqlalchemy/orm/session.py", line 350, in _prepare_impl
self.session.flush()
File "/Library/Python/2.7/site-packages/sqlalchemy/orm/session.py", line 1879, in flush
self._flush(objects)
File "/Library/Python/2.7/site-packages/sqlalchemy/orm/session.py", line 1997, in _flush
transaction.rollback(_capture_exception=True)
File "/Library/Python/2.7/site-packages/sqlalchemy/util/langhelpers.py", line 57, in __exit__
compat.reraise(exc_type, exc_value, exc_tb)
File "/Library/Python/2.7/site-packages/sqlalchemy/orm/session.py", line 1967, in _flush
flush_context.finalize_flush_changes()
File "/Library/Python/2.7/site-packages/sqlalchemy/orm/unitofwork.py", line 387, in finalize_flush_changes
self.session._register_newly_persistent(other)
File "/Library/Python/2.7/site-packages/sqlalchemy/orm/session.py", line 1389, in _register_newly_persistent
% state_str(state)
FlushError: Instance <Sighting at 0x10c6552d0> has a NULL identity key. If this is an auto-generated value, check that the database table allows generation of new primary key values, and that the mapped Column object is configured to expect these generated values. Ensure also that this flush() is not occurring at an inappropriate time, such aswithin a load() event.
The debugger caught an exception in your WSGI application. You can now look at the traceback which led to the error.
To switch between the interactive traceback and the plaintext one, you can click on the "Traceback" headline. From the text traceback you can also create a paste of it. For code execution mouse-over the frame you want to debug and click on the console icon on the right side.

You can execute arbitrary Python code in the stack frames and there are some extra helpers available for introspection:

dump() shows all variables in the frame
dump(obj) dumps all that's known about the object
1
Can you please provide the full stack trace of the error? ThanksMark Hildreth
thanks Mark, is the above traceback what you mean?tgh44

1 Answers

0
votes

You created the form, but unless I misread your code, you missed the step that actually populates the form with data from the POST (i.e. from request.form).