SQLite database not updating after inserting data from Flask python - python

I have an app route in a Flask web application, which under the "POST" method, takes data from a website form and is supposed to add an entry into a SQLite database (database.db) with that info in the table 'times'. The code runs without invoking any errors, but the database does not update with the added entry. The Flask app properly retrieves the info from the form. This is my code for connecting to the database and attempting to update it. Am I doing anything wrong?
connection=sqlite3.connect("database.db")
cursor=connection.cursor()
cursor.execute("INSERT INTO times (firstname, lastname, year, gender, event, minutes, seconds, milliseconds, date) VALUES(:first, :last, :year, :gender, :event, :minutes, :seconds, :milliseconds, :date)",
dict(first=first, last=last, year=year, gender=gender, event=event, minutes=minutes, seconds=seconds, milliseconds=milliseconds, date=date))
return redirect("/")

Missing connection.commit().
Please add that after the execute statement to save the entry in DB.

Related

Flask Sqlalchemy No Errors but not updating sqlite3 virtual table

I have a small flask app that I am working on. It consists of a search box, which is using a select statement outside of Sqlalchemy to do a "full text search" on a virtual fts5 table
sqlstr = "SELECT * FROM items INNER JOIN Restaurants on Restaurants.rest_id = items.restaurant_id WHERE items MATCH '{}' ORDER BY item_rank DESC".format(q)
crsr = conn.execute(sqlstr)
search_data = crsr.fetchall()
crsr.close()
The user gets the results and then can THumbs up a menu item from the results,when that happens I take them to a "vote" flask route to record the thumbs up AND make a log in my analytics table. and then redirect to last page. This is where it gets wonky.
db.session.query(items).filter(items.id==item_id).update({items.item_rank:items.item_rank +1})
db.session.commit()
## RECORDING IT IN ANALYTICS
voted_item = Analytics(user_id=str(current_user),action=str('vote'),item_id=item_id)
db.session.add(voted_item)
db.session.commit()
I don't get any errors in my log files. When I hit vote I get the flask message that says It was successful. I am successfully logging the vote in a separate Analytics table, but for some reason its not recording it in the items table.
Ive tried a few things. I went back to sql statement to update the items virtual table, something like this:
sqlstr = "UPDATE items SET item_rank = item_rank +1 where id = {}".format(item_id)
crsr = conn.execute(sqlstr)
crsr.close()
But I was getting data base is locked errors, I assume because I was access db outside of Sqlalchemy orm...Any ideas? Because of a fts5, virtual table? going back and forth form sql to orm?

How to get string value of user id type <class 'str'> [facebook messenger bot]

I'm creating facebook messenger app that is text based but does not require user to write specific commands.
I'm using python 3.6 and django 1.11.
The app asks for user's input and updates the phase that user has accomplished to database.
This system requires me to save user id to database and I have done that already. It works.
Instead.. when I try to create a database query it won't return any rows if I use the data from user's messenger message.
Here's how I create a record to database:
feedback_object, created = Feedback.objects.update_or_create(
source_created_at=feedback_start_at,
user_id=message['sender']['id'],
defaults={
'message': message['message']['text'],
'phase': feedback['phase']
}
Here's query that I CAN get the data from database:
r = Feedback.objects.filter(user_id='12345').latest('source_created_at')
Here's query that DOES NOT work but I need something similar:
r = Feedback.objects.filter(user_id=message['sender']['id']).latest('source_created_at')
Query doesn't return anything.
Solution: I went around this all by doing temporary db record that I can fetch and use in comparison with the original post.

Flask-Sqlalchemy: DB queries don't return new data

I'm building an app that receives webhooks from one service, stores the data in a database, then makes the data available via API.
I'm able to successfully add data to my app, but when I query the database I only receive the first commit from the that was in the database the last time I started the app.
For example, if I had 26 orders in the Orders table when I booted the app, then trigger the webhook, Order.query.all() will return 27 orders until I reboot the app, regardless of how many orders are actually in the table (I can validate using MySQL).
Here's an example of the class used to insert data into the table:
#webhook.route('/order/insert', methods=['POST'])
def insert_orders():
soda_json = request.json
db.session.add(Order(
order_id=soda_json['id'],
created_at=datetime.datetime.now(),
currency=soda_json['currency'],
total_line_items_price=soda_json['total_line_items_price'],
refunds=sum(float(i) for i in soda_json['refunds'] if soda_json['refunds']),
shipping_lines_price=sum([float(line['price']) for line in soda_json['shipping_lines']]),
note=soda_json['note']
))
db.session.commit()
return '200'
And here's a basic API method I'm using for testing:
order_test = Order.query.all()
#api.route('/display', methods=['POST', 'GET'])
def display_test():
return jsonify(json_list=[i.serialize for i in order_test]), '200'
What am I missing to always get the most recent data?
It looks like the order of methods in the query could be an issue.
from my_app.models import Order
order_test = Order.query.all()
That is the structure in the tutorial ( https://pythonhosted.org/Flask-SQLAlchemy/queries.html#querying-records ), but it seems like that might only be looking at data in the original imported model. Feel free to correct me on that.
In similar operations in the flask shell, I've had success getting live data right after commits with this query structure:
db.session.query([model]).all()
So a working example for API method might be:
#api.route('/display', methods=['POST', 'GET'])
def display_test():
order_test = db.session.query(Order).all()
return jsonify(json_list=[i.serialize for i in order_test]), '200'
The issue from what I can see is that order_list is only being populated when that view is initiated. So if you move that line of code to be within your route call it will then be refreshed every time that route is called.
e.g.
#api.route('/display', methods=['POST', 'GET'])
def display_test():
order_test = Order.query.all()
return jsonify(json_list=[i.serialize for i in order_test]), '200'
well from what you have said so far it seems that you are only able to add one new record to the DB no matter how many time new data is sent to the web hook and that if you restart the the API then you are back to square one and the new record is no longer there.
To me that seems to be a issue with committing the transaction in the webhook in that after the db.session.add() is called the data is not save to the db and so the transaction is left open and so when new data is added it is potentially overriding the data from the previous call and then when you end the API the transaction is either committed or rollbacked (can't remember the default action of flask-alchemy). you may need to check the data itself and see what data is being returned in the 51st row after the webhook is called and see if it changes after new data is sent to the webhook.
If you also compare your above webhook code and the below the commit and return lines are different. In yours they on a different tab line and are outside the webhook function and would not get run when the webhook is called so there would be an open transaction.
#webhook.route('/order/insert', methods=['POST'])
def insert_orders():
soda_json = request.json
db.session.add(Order(
order_id=soda_json['id'],
created_at=datetime.datetime.now(),
currency=soda_json['currency'],
total_line_items_price=soda_json['total_line_items_price'],
refunds=sum(float(i) for i in soda_json['refunds'] if soda_json['refunds']),
shipping_lines_price=sum([float(line['price']) for line in soda_json['shipping_lines']]),
note=soda_json['note']
))
db.session.commit()
return '200'

Updating the webpage using Flask based on MySQL database.

I have a webpage (built using HTML & jQuery) which displays the data from a MySQL database. I am using Flask to connect HTML with my database. However, my database gets updated every 15 minutes (using a separate Python Script). Currently, I stop the flask server, update the database and restart the Flask to update the webpage. My question is the following:
Is there a way to update the MySQL database in the background without having to stop the flask server? I read about concepts of AJAX and CRON, however i am not able to understand how to use them with flask asynchronously.
Note: I am a newbie in web applications and this is my first project which involves connecting client side and server side. Any help will be appreciated.
Thanks
You are most likely doing something like this:
from flask import Flask, render_template
from yourMySqlLibrary import connect_to_mysql
conn = connect_to_mysql()
# This is only executed when you start the script
data = conn.execute("SELECT * FROM MySemiRegularlyUpdatedTable")
app = Flask(__name__)
#app.route("/")
def view_data():
return render_template("view_data.html", data=data)
if __name__ == "__main__":
app.run()
If that is the case, then your solution is simply to move your connection and query calls into your controller so that the database is re-queried every time you hit the page:
#app.route("/")
def view_data():
# Removed from above and placed here
# The connection is made to the database for each request
conn = connect_to_mysql()
# This is only executed on every request
data = conn.execute("SELECT * FROM MySemiRegularlyUpdatedTable")
return render_template("view_data.html", data=data)
This way, your view will update when your data does - and you won't have to restart the server just to pick up changes to your data.

Web.py todo list example but with database in memory

First of all I must say I am a complete newbie to web.py.
I want to modify the todo list example to use a database in memory instead of using mysql.
I ended up writing:
import web
db = web.database(dbn="sqlite", db=":memory:")
db.query("CREATE TABLE todo (id INT AUTO_INCREMENT, title TEXT);")
def get_todos():
return db.select('todo', order='id')
def new_todo(text):
db.insert('todo', title=text)
def del_todo(id):
db.delete('todo', where="id=$id", vars=locals())
But when I open the website I get:
<class 'sqlite3.OperationalError'> at /
no such table: todo
Any idea?
I think it won't work by design, because webpy rerun all the program for each http request. So after at the second request, another database will be created so no persistence betwwen http requests.

Categories

Resources