I am trying to delete data from my database but my web application returns this error:
File "C:\Users\q\Pyc\Flask\basic_of_flask\SQL Database with flask\Database in view\adoption_sit.py", line 78, in del_pup
pup = db.session.get(id)
AttributeError: 'scoped_session' object has no attribute 'get'
have a look at my code below
import os
from flask import Flask, redirect, render_template, url_for
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
from form import AddForm, DelForm
app = Flask(__name__)
app.config['SECRET_KEY'] = 'mysecretkey'
#######################################
#### SQL DATABASE SECTION #############
#######################################
basedir = os.path.abspath(os.path.dirname(__file__))
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join(basedir, 'data.sqlite')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
Migrate(app, db)
########################################
######## Models ########################
########################################
class Puppy(db.Model):
__tablename__ = 'puppies'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Text)
def __init__(self, name):
self.name = name
def __repr__(self):
return f"Puppy name is {self.name}."
#############################################
##### VIEW FUNCTIONS -- HAVE FORM ###########
#############################################
#app.route('/')
def index():
return render_template('home.html')
#app.route('/add', methods=['GET', 'POST'])
def add_pup():
form = AddForm()
if form.validate_on_submit():
name = form.name.data
new_puppy = Puppy(name)
db.session.add(new_puppy)
db.session.commit()
return redirect(url_for('list_pup'))
return render_template('add.html', form=form)
#app.route('/list_pup')
def list_pup():
puppies = Puppy.query.all()
return render_template('list.html', puppies=puppies)
#app.route('/delete', methods=['GET', 'POST'])
def del_pup():
form = DelForm()
if form.validate_on_submit():
id = form.id.data
pup = db.session.get(id)
db.session.delete(pup)
db.session.commit()
return redirect(url_for('list_pup'))
return render_template('delete.html', form=form)
db.create_all()
if __name__ == '__main__':
app.run(debug=True)
and here is my form.py file
# form.py
from flask_wtf import FlaskForm
from wtforms import SubmitField, StringField, IntegerField
class AddForm(FlaskForm):
name = StringField('Name of puppy:')
submit = SubmitField('Submit puppy')
class DelForm(FlaskForm):
id = IntegerField("Id number of puppy to be remove:")
submit = SubmitField("Remove puppy")
i guess you are doing things the wrong way in del_pup() function
[..]
pup = db.session.get(id) # here
you need to get the Puppy object with the given id like:
#app.route('/delete', methods=['GET', 'POST'])
def del_pup():
form = DelForm()
if form.validate_on_submit():
id = form.id.data
# pup = db.session.get(id) # wrong way
pup = Puppy.query.filter_by(id=id).first()` # here
db.session.delete(pup)
db.session.commit()
return redirect(url_for('list_pup'))
return render_template('delete.html', form=form)
Related
this is my app.py code but i am receiving unbound local error after adding another path for delete and creating the function delete.
from crypt import methods
from email.policy import default
from flask import Flask, render_template, request, redirect
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///todo.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Todo(db.Model):
sno = db.Column(db.Integer, primary_key=True)
title = db.Column(db.String(200), nullable=False)
desc = db.Column(db.String(200), nullable=False)
date_created = db.Column(db.DateTime, default=datetime.utcnow)
def __repr__(self) -> str:
return f"{self.sno} - {self.title}"
#app.route('/', methods=['GET', 'POST'])
def hello_world():
if request.method == 'POST':
title = request.form["title"]
desc = request.form["desc"]
todo = Todo(title=title, desc=desc)
db.session.add(todo)
db.session.commit()
mytodo = Todo.query.all()
return render_template('index.html', mytodo=mytodo)
#app.route('/delete/<int:sno>')
def delete(sno):
todo = Todo.query.filter_by(sno==sno).first()
db.session.delete(todo)
db.session.commit()
return redirect('/')
if __name__ == "__main__":
app.run(debug=True, port=8000)
Below i've added the screenshot of the errors i am getting even when i just visit the root url.
Problem
If the server receive a GET /, then you won't define te title variable, but would try to use it at Todo(title=title, desc=desc) so an error
Fix
All the creation code should be in the if POST branch
#app.route('/', methods=['GET', 'POST'])
def hello_world():
if request.method == 'POST':
title = request.form["title"]
desc = request.form["desc"]
todo = Todo(title=title, desc=desc)
db.session.add(todo)
db.session.commit()
mytodo = Todo.query.all()
return render_template('index.html', mytodo=mytodo)
Here's my code:
from flask import Flask, render_template, request, redirect
from flask_sqlalchemy import SQLAlchemy
from datetime import datetime
app = Flask(__name__)
app._static_folder = 'static/'
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:test#localhost/Scheduling'
db = SQLAlchemy(app)
class CPR_INFO(db.Model):
DEAL_ID = db.Column(db.String(50), primary_key=True)
POG_NUM = db.Column(db.String(50))
OPOG_START_DT = db.Column(db.Date())
OPOG_END_DT = db.Column(db.Date())
def __repr__(self):
return 'Deal_ID ' + str(self.DEAL_ID)
#app.route('/')
def index():
return render_template('index.html')
#app.route('/posts', methods=['GET', 'POST'])
def posts():
if request.method == 'POST':
post_id = request.form['DEAL_ID']
post_title = request.form['POG_NUM']
post_content = request.form['OPOG_START_DT']
new_post = CPR_INFO(DEAL_ID = post_id, POG_NUM=post_title, OPOG_START_DT=post_content)
db.session.add(new_post)
db.session.commit()
return redirect('/posts')
else:
all_posts = CPR_INFO.query.all()
return render_template('posts-2.html', posts=all_posts)
#app.route('/posts/new', methods = ['GET', 'POST'])
def new_post():
if request.method == 'POST':
post_id = request.form['DEAL_ID']
post_title = request.form['POG_NUM']
post_content = request.form['OPOG_START_DT']
new_post = CPR_INFO(DEAL_ID=post_id, POG_NUM=post_title, OPOG_START_DT=post_content)
db.session.add(new_post)
db.session.commit()
return render_template('posts-2.html', posts=all_posts)
else:
return render_template('new_post_2.html')
#app.route('/posts/delete/<string:DEAL_ID>')
def delete(DEAL_ID):
post = CPR_INFO.query.get_or_404(DEAL_ID)
db.session.delete(post)
db.session.commit()
return redirect('/posts')
#app.route('/posts/edit/<string:DEAL_ID>', methods = ['GET', 'POST'])
def edit(DEAL_ID):
post = CPR_INFO.query.get_or_404(DEAL_ID)
if request.method == 'POST':
post.DEAL_ID = request.form['DEAL_ID']
post.POG_NUM = request.form['POG_NUM']
post.OPOG_START_DT = request.form['OPOG_START_DT']
db.session.commit()
return redirect('/posts')
else:
return render_template('edit-2.html', post = post)
if __name__ == "__main__":
app.run(debug=True)
This part of my code fails. The URL is not rendered because the DEAL_ID is not read:
#app.route('/posts/delete/<string:DEAL_ID>')
def delete(DEAL_ID):
post = CPR_INFO.query.get_or_404(DEAL_ID)
db.session.delete(post)
db.session.commit()
return redirect('/posts')
I get the following error message on my HTML page:
Not Found
The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.
Add methods parameter at your #app.route('/posts/delete/<string:DEAL_ID>')
I have written a CRUD API in flask but whenever I try to make a GET request, I get this error saying "internal server error". POST requests are also not working for me. POST return a 400 error saying that it is a bad request. What am I doing wrong here?
Following is my run.py file
from flask import Flask, jsonify, abort, request
from flask_restless import APIManager
from flask_sqlalchemy import SQLAlchemy
from flask import make_response
app = Flask(__name__)
app.config.from_pyfile('config.py')
db = SQLAlchemy(app)
class User(db.Model):
username = db.Column(db.String(50), primary_key=True)
password = db.Column(db.String(50))
name = db.Column(db.String(20))
def __init__(self, name, uname, pword):
self.username = uname
self.name = name
self.password = pword
#app.route('/api/users/', methods = ['GET'])
def index():
return jsonify({'users': User.query.all()})
#app.route('/api/<string:username>/')
def get_user(username):
return jsonify({'users': User.query.get(username)})
#app.errorhandler(404)
def not_found(error):
return make_response(jsonify({'error': 'Not found'}), 404)
#app.route('/api/users/', methods = ['POST'])
def create_user():
if not request.json or not 'name' in request.json:
abort(400)
user = User(request.json.username, request.json.get('name', ''), request.json.get('password',''))
db.session.add(user)
db.session.commit()
return jsonify( { 'User': user } ), 201
#app.route('/api/users/<string:username>', methods = ['DELETE'])
def delete_user(username):
db.session.delete(Users.query.get(username))
db.session.commit()
return jsonify( { 'result': True } )
#app.route('/api/users/<string:username>', methods = ['PUT'])
def update_user(username):
user = User.query.get(username)
user.username = request.json.get('username', ser.username)
user.name = request.json.get('name',user.name)
user.focus = request.json.get('password', user.password)
db.session.commit()
return jsonify( { 'user': user } )
if __name__ == '__main__':
app.run()
Following is my config.py file
import os
basedir = os.path.abspath(os.path.dirname(__file__))
SQLALCHEMY_DATABASE_URI = 'sqlite:///' + os.path.join(basedir, 'app.sqlite')
SQLALCHEMY_MIGRATE_REPO = os.path.join(basedir, 'db_repository')
What am I doing wrong here? Any help would be highly appreciated.
You need to 'create' the User table after you define its class, otherwise it doesn't show up in memory. http://flask-sqlalchemy.pocoo.org/2.1/api/#flask.ext.sqlalchemy.SQLAlchemy.create_all
The way to do it is:
class User(db.Model):
username = db.Column(db.String(50), primary_key=True)
password = db.Column(db.String(50))
name = db.Column(db.String(20))
def __init__(self, name, uname, pword):
self.username = uname
self.name = name
self.password = pword
db.create_all()
...the rest of your code
I can't figure out why I can't get passed the login page. It doesn't matter if I type in the right or wrong credentials, It reloads the login page, instead of signing me in.
import json
from flask import Flask, render_template, request, url_for, redirect
from flask.ext.bootstrap import Bootstrap
from flask.ext.login import LoginManager, UserMixin, login_required, login_user, current_user
from bson.objectid import ObjectId
from lib.mongo import db
from scripts.twitter_stats import ratio_of_wiki_links
app = Flask(__name__)
app.config["SECRET_KEY"] = ''
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login'
bootstrap = Bootstrap(app)
class User(UserMixin):
def __init__(self, name, password, id, active=True):
self.name = name
self.password = password
self.id = id
self.active = active
def is_active(self):
account = db.accounts.find_one({ "_id": ObjectId("561c7990e4b060b59d7cbcd1")})
if not account['username'] == self.name and account['password'] == self.password:
self.active = False
return self.active
def is_anonymous(self):
return False
def is_authenticated(self):
return True
def get_id(self):
return str(db.accounts.find_one({'username': self.name})['_id'])
#login_manager.user_loader
def load_user(userid):
user = db.accounts.find_one({'_id': userid})
return user
#app.route('/login', methods=['POST', 'GET'])
def login():
account = db.accounts.find_one({ "_id": ObjectId("561c7990e4b060b59d7cbcd1")})
password = account['password']
user = account['username']
error = None
if request.method == 'POST':
username = request.form['username']
passw = request.form['password']
if username != user or passw != password:
error = 'Invalid Credentials, please try again'
else:
user = User(username, passw, account['_id'])
login_user(user)
return redirect(url_for('home'))
return render_template('login.html', error=error)
#app.route('/')
#login_required
def home():
account = db.accounts.find_one({'account': 'twitter'})
entry = db.tweets.find().sort([['_id', -1]]).limit(1)
entry = list(entry)[0]['post']
# if g.user.is_authenticated():
# g.user = user.name
return render_template('index.html', account=account, entry=entry)
You should call add_routes before run app
if __name__ == '__main__':
add_routes(app)
app.run(debug=True)
For those of you struggling with the same issue, my problem was with the load_user method. I fixed it by changing it to this:
#login_manager.user_loader
def load_user(userid):
user_rec = db.accounts.find_one({'_id': ObjectId(userid)})
user = User(user_rec['username'], user_rec['password'], user_rec['_id'])
return user
APP CODE : There is no entry in the database and i am new at Flask and i am not able to connect to database and get entry into it and i am confused is my code is at all right
from flask import *
from wtforms import *
from wtforms.validators import Required
from flask.ext.wtf import Form
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.secret_key = 'MY CSI FORM'
branch_choices = [('CSE','CSE'),('ECE','ECE'),('MEC','MEC'),('CIVIL','CIVIL')]
year_choices = [('1st','1st'),('2nd','2nd'),('3rd','3rd'),('4th','4th')]
cmem_choices = [('Yes','Yes'),('No','No')]
class CSIForm(Form):
er = IntegerField('Enrollment No',validators=[Required()])
name = StringField('Name', validators=[Required()])
branch = SelectField('Branch',choices=branch_choices, validators=[Required()])
year = SelectField('Year',choices=year_choices, validators=[Required()])
cmem = SelectField('CSI Member',choices=cmem_choices,validators=[Required()])
sop = TextAreaField('Statement of Purpose', validators=[Required()])
submit = SubmitField('Submit')
DATABASE CODE : Code for database creation in SQLAlchemy dont know its correct or not
db = SQLAlchemy(app)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////tmp/test.db'
class CSI(db.Model):
__tablename__ = 'form'
er = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(30))
branch = db.Column(db.String(3))
year = db.Column(db.String(3))
cmem = db.Column(db.String(3))
sop = db.Column(db.String(50))
def __init__(self, er, name, branch, year, cmem, sop):
self.er = er
self.name = name
self.branch = branch
self.year = year
self.cmem = cmem
self.sop = sop
def connect_db():
db.create_all()
App running and connection
#app.route('/', methods=['GET', 'POST'])
def index():
form=CSIForm(request.form)
connect_db()
if form.validate_on_submit():
csi = CSI()
form.populate_obj(csi)
flash('Thanks for registering')
return render_template('form.html',form=form)
if __name__ == "__main__":
app.debug='True'
app.run()
You'll probably want to read up on sessions in SQLAlchemy. You need to add csi to your current session and commit the transaction.
def index():
form = CSIForm(request.form)
connect_db()
if form.validate_on_submit():
csi = CSI()
form.populate_obj(csi)
# These lines are new.
db.session.add(csi)
db.session.commit()
flash('Thanks for registering')