I have been reading the SQLAlchemy docs, but I don't understand them. The error (UnmappedInstanceError) says something isn't mapped. What isn't mapped? I really don't get sqlalchemy and I want to go back to using naked sqlite, but so many people recommend this, so I thought I should learn it. Here is the traceback:
File "C:\Users\Me\repos\mandj\venv\lib\site-packages\flask\app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Users\Me\repos\mandj\venv\lib\site-packages\flask\app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "C:\Users\Me\repos\mandj\venv\lib\site-packages\flask\app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\Me\repos\mandj\venv\lib\site-packages\flask\app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "C:\Users\Me\repos\mandj\venv\lib\site-packages\flask\app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Users\Me\repos\mandj\venv\lib\site-packages\flask\app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Users\Me\repos\mandj\venv\lib\site-packages\flask\app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Users\Me\repos\mandj\venv\lib\site-packages\flask\app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\Me\repos\mandj2\app\views.py", line 170, in add_manentry
db.session.add(q)
File "C:\Users\Me\repos\mandj\venv\lib\site-packages\sqlalchemy\orm\scoping.py", line 149, in do
return getattr(self.registry(), name)(*args, **kwargs)
File "C:\Users\Me\repos\mandj\venv\lib\site-packages\sqlalchemy\orm\session.py", line 1452, in add
raise exc.UnmappedInstanceError(instance)
UnmappedInstanceError: Class '__builtin__.unicode' is not mapped
Here is the applicable code:
#app.route('/addm', methods=['POST'])
def add_mentry():
if not session.get('logged_in'):
abort(401)
form = MForm(request.form)
filename = ""
if request.method == 'POST':
cover = request.files['cover']
if cover and allowed_file(cover.filename):
filename = secure_filename(cover.filename)
cover = cover.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
q = request.form['name']
# do for 12 more fields
db.session.add(q)
db.session.commit()
flash('New entry was successfully posted')
return redirect(url_for('moutput'))
When you are adding a non-model-object into the session, you will be getting UnmappedInstanceError.
In your case, q was probably an unicode string, not a model object. (It appears that you are using Python 2.x because in Python 3.x, it will say str), this was the line of the root cause for UnmappedInstanceError: Class '__builtin__.unicode' is not mapped:
File "C:\Users\Me\repos\mandj2\app\views.py", line 170, in add_manentry
db.session.add(q)
q = request.form['name']
# do for 12 more fields
db.session.add(q)
request.form['name'] will return a unicode value. Then, you do...
db.session.add(q)
The goal of the session is to keep track of Entities (Python objects), not individual unicode values as you seem to be trying to do it (See here for more on what the session does). Thus, you should be adding objects that have a mapping (such as a User object as shown in the "Mapping" section of the ORM tutorial), but you're actually passing a simple unicode value
What you're using is just one part of SQLAlchemy: the ORM (Object-Relational Mapper). The ORM will try to do things like allow you to create a new python object and have the SQL automatically generaeted by "adding" the object to the session..
a = MyEntity()
session.add(a)
session.commit() # Generates SQL to do an insert for the table that MyEntity is for
Keep in mind that you can use SQLAlchemy without using the ORM functionality. You could just do db.execute('INSERT...', val1, val2) to replace your already "naked" SQL. SQLAlchemy will provide you connection pooling, etc (although if you're using SQLite, you probably don't care about connection pooling).
If you want to understand Flask-SQLAlchemy, I would first recommend understanding how SQLAlchemy works (especially the ORM side) by trying it out using simple scripts (as shown in the tutorials. Then you'll understand how Flask-SQLAlchemy would work with it.
If you are changing database see:
You have to address to what item in the object you want to change. See below:
client = session.query(Clients).filter_by(id=client_id).one()
if request.method == 'POST':
new_name = request.form['form_name']
client.name = new_name
session.add(client)
session.commit()
As you can see in the 'client' object, we have "name" among other info inside the object. We want to directly change 'name' only, therefore you need to address to it. (client.name)
If you are adding new thing to database:
Here when you add a new value to the database with orm, you need to specify the item in the object that is receiving the data.
in this case (Client.name)
if request.method == 'POST':
new_name = request.form['form_name']
name = Clients(name=new_name)
session.add(name)
session.commit()
Hope that helps.
I came across a problem like this. In the following code below, I tried to delete some posts:
#app.route('/categorydeletion', methods=['POST'])
def deletecategory():
name_of_category = request.form['categoryname']
category_to_be_deleted = Category.query.filter_by(name=name_of_category).first()
accompained_post = Posts.query.filter_by(category_id=category_to_be_deleted.id).all()
if category:`enter code here`
db.session.delete(category_to_be_deleted)
db.session.delete(accomapained_post)
db.session.commit()
return 'successful
But I was getting the same error sqlalchemy.orm.exc.UnmappedInstanceError
So my fix was this below:
#app.route('/categorydeletion', methods=['POST'])
def deletecategory():
name_of_category = request.form['categoryname']
category_to_be_deleted = Category.query.filter_by(name=name_of_category).first()
accompained_post = Posts.query.filter_by(category_id=category_to_be_deleted.id).all()
if category:
db.session.delete(category_to_be_deleted)
def delete_accomapained_post():
for i in accompained_post:
db.session.delete(i)
delete_accomapained_post()
db.session.commit()
return 'successful'
As #devy pointed out, you work with python objects; with the first scenario I was working with a python list.
But in the second scenario, I had to create a function delete_accomapained_post() to loop through the list to access the Python objects that I want to work with.
Related
I'm having trouble in a flask application with an object. The first time the function is run, it runs perfectly fine. The second time it is run, however, I get an error that 'str' object has no attribute SubmitFeedResult. I'm able to get around this by restarting the application and running the function again (which then runs fine). The object is being changed to a string after the function is run, and I am wondering if there is a way to prevent the object's class from changing to string (I am leaning towards no because it does this due to the source code in the library that I am using), or what a good way around this issue would be. For the application to run successfully for other users, I cannot have an object with class str
I asked this question a few months ago, solving it briefly but now the issue has come back. This is the link to the original post for some context: 'str' Object has no attribute 'SubmitFeedResult'
Here is the main function:
#app.route('/submission/', methods=['GET','POST'])
def feed_submission():
if request.method == 'POST':
file = request.files['file']
# Only XML files allowed
if not allowed_filetype(file.filename):
output = '<h2 style="color:red">Filetype must be XML! Please upload an XML file.</h2>'
return output
raise ValueError('Filetype Must Be XML.')
# Read file and encode it for transfer to Amazon
file_name = request.form['file_name']
f = file.read()
u = f.decode("utf-8-sig")
c = u.encode("utf-8")
feed_content = c
submit_feed_response = conn.submit_feed(
FeedType=feed_operation(file_name),
PurgeAndReplace=False,
MarketplaceIdList=[MARKETPLACE_ID],
content_type='text/xml',
FeedContent=feed_content)
feed_info = submit_feed_response.SubmitFeedResult.FeedSubmissionInfo.FeedSubmissionId
return redirect(url_for('feed_result', feed_id=feed_info))
else:
return render_template('submit_feed.html',access_key=MWS_ACCESS_KEY,secret_key=MWS_SECRET_KEY,
merchant_id=MERCHANT_ID,marketplace_id=MARKETPLACE_ID)
After this function runs, it redirects to this function to return the response of the request:
#app.route('/feed-result/<int:feed_id>')
def feed_result(feed_id):
response = MWSConnection._parse_response = lambda s,x,y,z: z
submitted_feed = conn.get_feed_submission_result(FeedSubmissionId=feed_id)
result = Response(submitted_feed, mimetype='text/xml')
return(result)
I logged the information of the types and values of submit_feed_response before the issue happens and after to see what is causing the error:
typeof1 = type(submit_feed_response)
val1 = submit_feed_response
typeof_conn1 = type(conn)
app.logger.warning("Type of submit_feed_response (original): " + str(typeof1))
app.logger.warning("Value of submit_feed_response: " + str(val1))
In the logs, when the app runs as it should, I see:
Type of submit_feed_response (original): <class 'boto.mws.response.SubmitFeedResponse'>
Value of submit_feed_response: SubmitFeedResponse{u'xmlns': u'http://mws.amazonaws.com/doc/2009-01-01/'}(SubmitFeedResult: SubmitFeedResult{}(FeedSubmissionInfo: FeedSubmissionInfo{}...
After it fails, I see (as expected) the type is string:
Type of submit_feed_response: <type 'str'>
Value of submit_feed_response: <?xml version="1.0"?>
......
Here is the traceback:
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\flask\app.py", line 2000, in __call__
return self.wsgi_app(environ, start_response)
File "C:\Python27\lib\site-packages\flask\app.py", line 1991, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "C:\Python27\lib\site-packages\flask\app.py", line 1567, in handle_exception
reraise(exc_type, exc_value, tb)
File "C:\Python27\lib\site-packages\flask\app.py", line 1988, in wsgi_app
response = self.full_dispatch_request()
File "C:\Python27\lib\site-packages\flask\app.py", line 1641, in full_dispatch_request
rv = self.handle_user_exception(e)
File "C:\Python27\lib\site-packages\flask\app.py", line 1544, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "C:\Python27\lib\site-packages\flask\app.py", line 1639, in full_dispatch_request
rv = self.dispatch_request()
File "C:\Python27\lib\site-packages\flask\app.py", line 1625, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "C:\Users\CTS 41\Documents\Amazon-app\application.py", line 98, in feed_submission
feed_info = submit_feed_response.SubmitFeedResult.FeedSubmissionInfo.FeedSubmissionId
AttributeError: 'str' object has no attribute 'SubmitFeedResult'
It seems that the library is causing the object to return a string once it is run. Is there a good, pythonic way around this? i.e. am I able to somehow change the class of the object to ensure it stays that, or delete it from memory completely? I've tried a try except block, and that comes back with the same error.
EDIT
I have narrowed the issue down to:
response = MWSConnection._parse_response = lambda s,x,y,z: z in the function feed_result. It is there to return the XML response from boto (the call does not naturally come back in XML format, and I am not sure of another way to return it in XML, refer to How can I return XML from boto calls?).
I decided to insert
MWSConnection._parse_response = None above the line
feed_info = feed.SubmitFeedResult.FeedSubmissionInfo.FeedSubmissionId, however it is still coming back with the same error. Is there a way I can clear this function from memory after it is run once? I need this function to properly serve the response, but perhaps there is a better way?
I was able to solve this. The issue, as stated in the question, was stemming from the line response = MWSConnection._parse_response = lambda s,x,y,z: z in feed_result. This line is necessary to parse the response into XML and to serve it, which was causing the response for the submission of the feed to be parsed into an XML string after this function was called. To solve this, I checked to see if feed was not a string, and retrieved the ID as I originally did:
if type(feed) is not str:
feed_info = feed.SubmitFeedResult.FeedSubmissionInfo.FeedSubmissionId
If it is a string, it is parsed as an XML string using ElementTree to retrieve the ID:
else:
tree = et.fromstring(feed)
xmlns = {'response': '{http://mws.amazonaws.com/doc/2009-01-01/}'}
info = tree.find('.//{response}FeedSubmissionId'.format(**xmlns))
feed_info = info.text
Which now works as it should without having to restart the application.
This question already has an answer here:
"TypeError": 'list' object is not callable flask
(1 answer)
Closed 6 years ago.
*this question is not a duplicate of another question and I have already tried the answer given in that question and it did not solve
my problem. Thanks.
I'm a beginner in Python and learning how to use SQLalchemy.
I am trying to retrieve all rows from my database table
returning the results as a list of objects
my js code will read the list of objects and display into view
However I have been getting this list object is not callable error. Can someone give me a guide on this please thank you.
#mod_core.route('/getDatatable', methods=['GET'])
def datatable_get():
# Query 'user' table.
_user = User.query.all()
_results = []
for user in _user:
print user.get_all()
_results.append(user.get_all())
return _results
127.0.0.1 - - [22/Jan/2017 17:10:46] "GET /getDatatable HTTP/1.1" 500 -
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 2000, in call
return self.wsgi_app(environ, start_response)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1991, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/local/lib/python2.7/dist-packages/flask_restful/init.py", line 271, in error_router
return original_handler(e)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1567, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1988, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1642, in full_dispatch_request
response = self.make_response(rv)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1746, in make_response
rv = self.response_class.force_type(rv, request.environ)
File "/usr/local/lib/python2.7/dist-packages/werkzeug/wrappers.py", line 847, in force_type
response = BaseResponse(*_run_wsgi_app(response, environ))
File "/usr/local/lib/python2.7/dist-packages/werkzeug/wrappers.py", line 57, in _run_wsgi_app
return _run_wsgi_app(*args)
File "/usr/local/lib/python2.7/dist-packages/werkzeug/test.py", line 871, in run_wsgi_app
app_rv = app(environ, start_response)
TypeError: 'list' object is not callable
UPDATE 1 : I have also tried changing User to Json before returning and still gets the same error:
#mod_core.route('/getDatatable', methods=['GET'])
def datatable_get():
# Query 'user' table.
_user = User.query.all()
results = []
for user in _user:
results.append(user.to_json())
print results
return results
User class
def to_json(self):
"""
Return a JSON response for RESTful API GET request.
"""
_user_in_josn = {'login_id': self.login_id,
'fullname': self.fullname,
'nickname': self.nickname,
'matric': self.matric_no,
'email': self.email,
'alt_email': self.alt_email
}
return _user_in_josn
UPDATE 2 : Tried to cast to JSON before returning results
User object at 0x7f88f80b14d0> is not JSON serializable
PLease guide me along. Thank you for your kind attention and help.
I'm not sure exactly where your problem is coming from, but I do see a confusing thing you're doing with your user objects. You've obtained a user in your loop, but you're still calling user.get_all(). I'm not sure what that is supposed to do because, at that point, user is just one user object. Do you want the user's database ID? Some other piece of data like the username?
Try changing that line to something like this:
_results.append(user.id)
That will add the user's ID to your list. Or you could append whatever other data you have stored in your user object. If you want to return a full list of all users in your database, then do this:
return _user
I might also suggest renaming those variables _user and _results. Using the leading underscore is usually just for hidden variables, and there doesn't seem to be any need for that here. Also, since _user stores many user objects, a name like users would probably be more appropriate to indicate what the variable contains.
I want to select (and return) one field only from my database with a "where clause". The code is:
from sqlalchemy.orm import load_only
#application.route("/user", methods=['GET', 'POST'])
def user():
user_id = session.query(User, User.validation==request.cookies.get("validation")).options(load_only("id"))
session.commit()
return user_id
This fails and the traceback is:
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 1478, in full_dispatch_request
response = self.make_response(rv)
File "/Library/Python/2.7/site-packages/flask/app.py", line 1577, in make_response
rv = self.response_class.force_type(rv, request.environ)
File "/Library/Python/2.7/site-packages/werkzeug/wrappers.py", line 841, in force_type
response = BaseResponse(*_run_wsgi_app(response, environ))
File "/Library/Python/2.7/site-packages/werkzeug/wrappers.py", line 57, in _run_wsgi_app
return _run_wsgi_app(*args)
File "/Library/Python/2.7/site-packages/werkzeug/test.py", line 867, in run_wsgi_app
app_rv = app(environ, start_response)
TypeError: 'Query' object is not callable
How can I select and return just the "id" column? I have tried several other ways too but also with failure. Is "load_only" the correct option?
A Query object accepts entities to query as positional arguments, so just pass it User.id:
user_id = session.query(User.id).\
filter(User.validation == request.cookies.get("validation")).\
scalar()
scalar() returns the first element of the first result or None, if no rows were found. It raises MultipleResultsFound exception for multiple rows.
load_only() indicates that only the given column-based attributes of an entity should be loaded and all others, expect the identity, will be deferred. If you do need the whole User model object later, this can be the way to go. In that case your original query has to change to:
user = session.query(User).\
filter(User.validation == request.cookies.get("validation")).\
options(load_only("id")).\
one()
one() returns exactly one result or raises an exception (0 or more than 1 result). If you accept None as a valid return value for "no user found", use one_or_none().
Note that predicates, the criteria of the WHERE clause, should not be passed to the Query object as entities, but added with filter().
To top it off, views in Flask expect that you return one of:
a valid response object
a string
a (response, status, headers) tuple
a WSGI application
The machinery will treat anything other than a response object, a string or a tuple as a WSGI application. In your original code you returned a Query object because of the missing call to scalar() or such and this was then treated as a WSGI app.
Note: If you call Model.query(params) you would see the following error
ERROR: 'BaseQuery' object is not callable
You need to call query(params) on session
example:
rows = session.query(Model.name).filter(Model.age >= 20).all()
Alternative:
You can do this using with_entities
example: To fetch names & age where age is greater than 20
rows = Model.query.with_entities(Model.name, Model.age).filter(Model.age >= 20).all()
To query the content of one column instead of the entire table flask-sqlalchemy, which I suppose can give you a hint about sqlalchemy itself would work gets you to query the session as you are doing, with a different syntax.
If your table looks something like:
class User(...):
id = db.Column(db.Integer, primary_key=True)
...
You can query it with:
user_ids = session.query(User.id)
all_ids = user_ids.all()
This returns a list of all User Ids.
You would have to do something along these lines:
session.query(Table.col1).filter(User.name=='Name')
The problem has nothing to do with queries and db connection. Inside #application.route("/user", methods=['GET', 'POST']) statement you return a user_id which is a result of a select from database. In Flask you should return something appropriate.
This question already has answers here:
Why does code like `str = str(...)` cause a TypeError, but only the second time?
(20 answers)
Closed 8 years ago.
I am running into an issue I cannot seem to resolve.
I have created a Python package containing amongst many things a function inside a class that sends a query to a database and retrieves the results.
I also have a seperate program that uses that function.
The whole thing looks like this:
Oddjob (seperate python module):
def query(self, query):
"""
Running a query against Oddjob and returning result
:param query: The query to run
:return:
"""
try:
qr = self.c.execute(query)
qry = self.c.fetchall()
except Exception, e:
qry = e
return qry
This ^^^ is what is being called.
The query that needs to be run is kept in a variable as such:
sAvail = "exec sp_avi #week='32'"
And gets called like this:
SAvailability(oddjob.query(str(sAvail)))
Just for information, SAvailability is this code:
def SAvailability(result):
shipped = result[0]
onhold = result[1]
percentWO = 100 / int(shipped)
percentOnHold = percentWO * int(onhold)
total = str(int(math.floor(100 - percentOnHold)))
return total
Please note however, I provide the SAvailability function only for clarification, when I use query together with another function I get the same problem:
TypeError: 'str' object is not callable
The full traceback is:
File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1836, in __call__
return self.wsgi_app(environ, start_response)
File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1820, in wsgi_app
response = self.make_response(self.handle_exception(e))
File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1403, in handle_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1817, in wsgi_app
response = self.full_dispatch_request()
File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1477, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1381, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1475, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/lib/python2.7/dist-packages/flask/app.py", line 1461, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/arthur/Dropbox/Scaramanga_Development/scaramanga/server.py", line 1062, in dashboard_HEAD
SAvailability(oddjob.query(str(sAvail))),
TypeError: 'str' object is not callable
I have tried adding str() left, right, and centre, but nothing seems to change it.
Can anyone see anything obvious I am missing?
I have tried adding str() left, right, and centre, but nothing seems to change it. Can anyone see anything obvious I am missing?
I guess you some where set str="blablabla".
print type(str) check the result, try del str if print output is str
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
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).