Flask : Data not saved on server restart/close - python

I just started learning to develop on Flask (through the 'fullstack' course on Udacity).
But I was wondering, is it normal that when I restart/close my server all the data I had changed from my "website" while the server was previously up, is gone? (I don't know if I clearly explained the problem).
If yes, how to make it so that the data is saved in the database even if I close the server?
this is an example of what the code looks like:
from flask import Flask, render_template, request, redirect, url_for, flash, jsonify
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from database_setup import Base, Restaurant, MenuItem
app = Flask(__name__)
engine = create_engine('sqlite:///restaurantmenu.db')
Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()
(...)
#app.route('/restaurants/<int:restaurant_id>/new', methods=['GET', 'POST'])
def newMenuItem(restaurant_id):
if request.method == 'POST':
newItem = MenuItem(name=request.form['name'], description=request.form['description'], price=request.form['price'], course=request.form['course'], restaurant_id=restaurant_id)
session.add(newItem)
session.commit
flash("new menu item created !")
return redirect(url_for('restaurantMenu', restaurant_id=restaurant_id))
else:
return render_template('newmenuitem.html', restaurant_id=restaurant_id)
(...)
if __name__ == '__main__':
app.secret_key = 'super_secret_key'
app.debug = True
app.run(host = '0.0.0.0', port=5000)

Just copying my comment into an answer.
If this is working code you posted try using session.commit() with he brackets. Right now you never call commit and nothing will be stored in the database.

Related

Passing python objects from main flask app to blueprints

I am trying to define a mongodb object inside main flask app. And I want to send that object to one of the blueprints that I created. I may have to create more database objects in main app and import them in different blueprints. I tried to do it this way.
from flask import Flask, render_template
import pymongo
from admin_component.bp1 import bp_1
def init_db1():
try:
mongo = pymongo.MongoClient(
host='mongodb+srv://<username>:<passwrd>#cluster0.bslkwxdx.mongodb.net/?retryWrites=true&w=majority',
serverSelectionTimeoutMS = 1000
)
db1 = mongo.test_db1.test_collection1
mongo.server_info() #this is the line that triggers exception.
return db1
except:
print('Cannot connect to db!!')
app = Flask(__name__)
app.register_blueprint(bp_1, url_prefix='/admin') #only if we see /admin in url we gonna extend things in bp_1
with app.app_context():
db1 = init_db1()
#app.route('/')
def test():
return '<h1>This is a Test</h1>'
if __name__ == '__main__':
app.run(port=10001, debug=True)
And this is the blueprint and I tried to import the init_db1 using current_app.
from flask import Blueprint, render_template, Response, request, current_app
import pymongo
from bson.objectid import ObjectId
import json
bp_1 = Blueprint('bp1', __name__, static_folder='static', template_folder='templates')
print(current_app.config)
db = current_app.config['db1']
But it gives this error without specifying more details into deep.
raise RuntimeError(unbound_message) from None
RuntimeError: Working outside of application context.
This typically means that you attempted to use functionality that needed
the current application. To solve this, set up an application context
with app.app_context(). See the documentation for more information.
Can someone point out what am I doing wrong here??
The idea you are attempting is correct; however it just needs to be done a little differently.
First, start by declaring your mongo object in your application factory:
In your app/__init__.py:
import pymongo
from flask import Flask
mongo = pymongo.MongoClient(
host='mongodb+srv://<username>:<passwrd>#cluster0.bslkwxdx.mongodb.net/?retryWrites=true&w=majority',
serverSelectionTimeoutMS = 1000
)
# Mongo is declared outside of function
def create_app(app):
app = Flask(__name__)
return app
And then in your other blueprint, you would call:
from app import mongo # This right here will get you the mongo object
from flask import Blueprint
bp_1 = Blueprint('bp1', __name__, static_folder='static', template_folder='templates')
db = mongo

flask session - TypeError: 'type' object does not support item assignment

I'm trying to verify a user using flask session. The problem is that whenever I try to assign a value to my session, I get the error:
TypeError: 'type' object does not support item assignment
I have seen This stack overflow question and I have been using guides such as this one, however I have been unable to solve this problem.
Code:
from flask import Flask, redirect, url_for, request, render_template
from flask_session import Session
if request.method == 'POST':
username = request.form['un']
password = request.form['pw']
Session['name'] = request.form['un'] #this is where my error is occuring
else:
username = request.args.get('un')
password = request.args.get('pw')
Session["name"] = request.args.get('un')
I thought that my error could have been related to request.form['un'], so I changed the code to:
from flask import Flask, redirect, url_for, request, render_template
from flask_session import Session
if request.method == 'POST':
username = request.form['un']
password = request.form['pw']
Session['test'] = 'test' #still have an error here
else:
username = request.args.get('un')
password = request.args.get('pw')
Session["test"] = "test"
App is setup like this:
app = Flask(__name__, template_folder='template')
app.config["SESSION_PERMANENT"] = True
app.config["SESSION_TYPE"] = "filesystem"
app.secret_key = 'why would I tell you my secret key?'
app.config.from_object(__name__)
Session(app)
If this is something silly then I apologize for wasting your time :). I would appreciate any help.
Thanks
You are trying to assign the value to Session object.
If you check the example on the project's repo, you'll see it assigns the value to flask session, not flask_session's Session object:
from flask import Flask, session
from flask_session import Session
SESSION_TYPE = 'redis'
app = Flask(__name__)
app.config.from_object(__name__)
Session(app)
#app.route('/set/')
def set():
# check here
# it is flask's session, not flask_session's Session object
session['key'] = 'value'
return 'ok'
#app.route('/get/')
def get():
return session.get('key', 'not set')
if __name__ == "__main__":
app.run(debug=True)

Key Error in Flask Sessions

So I have been using sessions to pass data from one decorator to another. But now every time I make a new session variable, I get a KeyError from page to page. Meaning, I had a session error from my third to fourth page; but I had the same issue adding a new session variable from my second to third page even though I have four other session variables that give me no error.
My code is similar to the one #laila posted below:
from flask import Flask, render_template
from flask import request, session, url_for,abort,redirect
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
#app.route('/'):
def first():
session['this_one']='hello'
render('template.html')
#app.route('/second')
def second():
it=session['this_one']
render('other_page.html')
if __name__ == '__main__':
app.run(debug=True)
it seems like the code has some syntax error.Please try the code below, it should be ok:
from flask import Flask, render_template
from flask import request, session, url_for, abort, redirect
app = Flask(__name__)
app.config['SECRET_KEY'] = 'secret'
#app.route('/')
def first():
session['this_one'] = 'hello'
return render_template('template.html')
#app.route('/second')
def second():
it = session.get('this_one', 'not found')
return render_template('other_page.html')
if __name__ == '__main__':
app.run(debug=True)

Flask error setting session attribute: BadPayload

I'm having trouble setting a flask session attribute. I cannot set session['var_name'] to anythign without getting a BadPayload: Could not load the payload because an exception occurred on unserializing the data error. The below code throws an error. but if I comment out session['a'] = 1 and it runs fine. Seem's like its an itsdangerous error. Should I be setting me secret_key to something better than gobblygook? Is that related?
from flask import Flask, render_template, session
app = Flask(__name__)
app.secret_key = 'sdfnbsifhosdfsdsfsddfsdfiewl'
#app.route('/', methods=['GET','POST'])
def index():
session['a'] = 1
return render_template('index.html')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7777, debug=True)

Flask-SQLAlchemy, "Application not registered on db"

I have the following Flask app running on one machine:
app.py
from flask import Flask
from aves.extensions import db
def create_app(config_object=DevConfig):
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:password#localhost/dbname'
register_extensions(app)
return app
def register_extensions(app):
db.init_app(app)
query = "SELECT * FROM score LIMIT 50;"
result = db.engine.execute(query)
print(list(result))
return None
extensions.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
Now, I used pgAdmin's backup function to export my database, and import it again to a new machine. I try to run the same code, but now I'm getting the following error:
RuntimeError: application not registered on db instance and no application bound to current context
I had the database running on the new machine before, then I worked on the code n the other machine for a while, and now that I try it again on the new one it doesn't work (maybe its somehow still bound to the old database or something?).
When I try a simple script like the one below and run it, it works fine.
test_db_connection.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:password#localhost/dbname'
db = SQLAlchemy(app)
query = "SELECT * FROM score LIMIT 50;"
result = db.engine.execute(query)
print(list(result))
I got it to run by adding the following line to app.py: with app.app_context():
def create_app(config_object=DevConfig):
app = Flask(__name__)
with app.app_context():
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:password#localhost/dbname'
register_extensions(app)
return app

Categories

Resources