I am working in a small website where I want to show, insert, edit and delete elements from the database
I accomplished showing the data with this route:
#app.route('/objects')
def objects():
g.db = sqlite3.connect(db_location)
cur = g.db.execute('SELECT * FROM milkyway ORDER BY type')
objects = [dict(id=row[0], type=row[1], name=row[2], description=row[3], size=row[4], mass=row[5],distance=row[6], discoverer=row[7], image_url=row[8]) for row in cur.fetchall()]
g.db.close()
return render_template("objects.html",objects=objects)
And now I am trying to insert an element but I receive an error "AttributeError: '_AppCtxGlobals' object has no attribute 'db'"
#app.route('/insert_value',methods = ['POST', 'GET'])
def insert_value():
atype = request.form['type']
name = request.form['name']
description = request.form['description']
size = request.form['size']
mass = request.form['mass']
distance = request.form['distance']
discoverer = request.form['discoverer']
image_url = request.form['image_url']
g.db.execute('INSERT INTO milkyway (type,name,description,size,mass,distance,discoverer,image_ur) VALUES (?,?,?,?,?,?,?,?)', [atype], [name], [description], [size], [mass], [distance], [discoverer], [image_url] )
g.db.commit()
return redirect(url_for('objects'))
I search everywhere but the thing is, there are so many different ways to do this and I cannot make it works. I followed for instance this example; http://opentechschool.github.io/python-flask/extras/databases.html
The connection, g.db, needs to be added with each request. You only create it in objects, so it doesn't exist for insert_value. g is an object which is created in the context of each request.
As the example code shows, you should create the connection before each request and add it to g.
#app.before_request
def before_request():
g.db = sqlite3.connect(db_location)
Be sure to also close it in #app.teardown_request.
Related
So, basically i have a task managing application i am working on, and i need a way to detect if there's no tasks in the database so i can make a simple jinja2 format on it.
Here is my code:
#app.route("/dashboard")
def dashboard():
if "name" in session:
username = session['name']
ifTask = taskAdd.find({"name": username})
name = session['name']
tasknames = []
if ifTask is None:
return render_template('dashboard.html', noTasksDB=True)
for x in ifTask:
tasknames.append((x['taskname'], x['Priority'], x['Notfication']))
return render_template('dashboard.html', dashboardPage=True, title=name+"'s Dashboard", name=True, username=username, ifTask=ifTask, tasknames=tasknames, noTasksDB=False)
I tried to add the following code:
if ifTask is None:
return render_template('dashboard.html', noTasksDB=True)
I expected None to work, but it didn't instead the HTML remained the same .
I also tried printing ifTask when there are no current tasks in the database and all i get is some pymongo cursor which i have no idea on what it means.
Does anyone know how to fix this problem?
If you do as the other commenter suggested, but change your comparison a bit then this should work. ifTask will be an empty list if nothing is found - and then we just check if it's empty rather than comparing it to None.
ifTask = list(taskAdd.find({"name": username}))
if not ifTask:
return render_template('dashboard.html', noTasksDB=True)
or if you don't want to do that. Then
ifTask = taskAdd.find({"name": username})
name = session['name']
tasknames = []
for x in ifTask:
tasknames.append((x['taskname'], x['Priority'], x['Notfication']))
if not tasknames:
# tasknames is an empty list - no tasks
return render_template('dashboard.html', noTasksDB=True)
return render_template(
'dashboard.html',
dashboardPage=True,
title=name+"'s Dashboard",
name=True,
username=username,
ifTask=ifTask,
tasknames=tasknames,
noTasksDB=False
)
tasknames will be empty if taskAdd.find didn't find any results.
I've been building a webapp for the HR department which will (hopefully) include the ability for staff to submit timesheets and I have become stuck when trying to submit a timesheet. The connection string is working as I can see other data from the database. I have been working through errors but this 07002 error is one I can't work out what is causing it.
I've tried two different ways to get this working. Here is the first attempt in my app.py file -
#app.route('/timesheet', methods=['GET', 'POST'])
def employee_timesheet():
if request.method == "POST":
employee_id = request.form['employee_id']
department = request.form['department']
mondaystart = request.form['mondaystart']
mondayend = request.form['mondayend']
tuesdaystart = request.form['tuesdaystart']
tuesdayend = request.form['tuesdayend']
wednesdaystart = request.form['wednesdaystart']
wednesdayend = request.form['wednesdayend']
thursdaystart = request.form['thursdaystart']
thursdayend = request.form['thursdayend']
fridaystart = request.form['fridaystart']
fridayend = request.form['fridayend']
saturdaystart = request.form['saturdaystart']
saturdayend = request.form['saturdayend']
result = request.form
cursor = cnxn.cursor()
cursor.execute('''INSERT INTO dbo.submitted_timesheet (employee_id, department, mondaystart, mondayend, tuesdaystart, tuesdayend, wednesdaystart, wednesdayend, thursdaystart, thursdayend, fridaystart, fridayend, saturdaystart, saturdayend,) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)''')
cnxn.commit()
flash("Your form was successfully submitted")
print("Form data submitted")
return redirect (url_for('success.html', result=result))
return render_template("staff_timesheets.html")
The other way then is -
#app.route('/timesheet', methods=['GET', 'POST'])
def employee_timesheet():
if request.method == "POST":
employee_id = request.form['employee_id']
department = request.form['department']
mondaystart = request.form['mondaystart']
mondayend = request.form['mondayend']
tuesdaystart = request.form['tuesdaystart']
tuesdayend = request.form['tuesdayend']
wednesdaystart = request.form['wednesdaystart']
wednesdayend = request.form['wednesdayend']
thursdaystart = request.form['thursdaystart']
thursdayend = request.form['thursdayend']
fridaystart = request.form['fridaystart']
fridayend = request.form['fridayend']
saturdaystart = request.form['saturdaystart']
saturdayend = request.form['saturdayend']
insert_query = '''INSERT INTO submitted_timesheet (employee_id, department, mondaystart, mondayend, tuesdaystart, tuesdayend, wednesdaystart, wednesdayend, thursdaystart, thursdayend, fridaystart, fridayend, saturdaystart, saturdayend,) VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?)'''
result = request.form
cursor = cnxn.cursor()
cursor.execute(insert_query, values)
cnxn.commit()
flash("Your form was successfully submitted")
print("Form data submitted")
return redirect (url_for('success.html', result=result))
return render_template("staff_timesheets.html")
If I submit a timesheet, I get the Pyodbc error in the title. Everything matches up in terms of column names and types. The HTML form should be fine too but can post it if needed for context.
Any ideas where I am going wrong?
Thank you!
I want to have a MongoDB operation in a celery task but im facing some issues while accessing the instance variables.
Heres the code
app = CeleryConnector().app
class CeleryTasks:
def __init__(self, port, docID, dbName, collName, data):
self.port = port
self.docID = docID
self.dbName = dbName
self.collName = collName
self.data = data
self.client = MongoClient(host='localhost', port=port, username='admin', password='password')
self.db = self.client[dbName]
print ("CeleryTasks:init")
#app.task
def createDoc(dbName, collName, data):
print ("CeleryTasks:CreateDoc")
if 'refs' not in data:
return
# Here is the error I dont know how to access the client variable here.
#db = client[dbName]
print(data['refs'])
for id in data['refs']:
doc = db[collName].find_one({'_id': id})
if doc is None:
insertedID = db[collName].insert_one({
"_id": id
})
print (insertedID)
#app.task(bind=True)
def createDoc(self, dbName, collName, data):
print ("CeleryTasks:CreateDoc")
if 'refs' not in data:
return
print(data['refs'])
for id in data['refs']:
doc = self.db[collName].find_one({'_id': id})
if doc is None:
insertedID = self.db[collName].insert_one({
"_id": id
})
print (insertedID)
As we cannot pass non JSON serializable objects to a Task so passing db or client is not an option.
Problem with the first function
I dont know how to access client inside it. Tried a few things but failed.
Problem with the second function
It gives an error doc = self.db[collName].find_one({'_id': id})
AttributeError: 'createDoc' object has no attribute 'db'
etc etc
How to make this work or how to access instance variables inside celery tasks?
I added a check on a Post method to only let appointments on different dates pass through but I don't know how to return an error msg. here's the code
from flask_restful import Resource, Api, request
from package.model import conn
class Appointments(Resource):
def get(self):
appointment = conn.execute("SELECT p.*,d.*,a.* from appointment a LEFT JOIN patient p ON a.pat_id = p.pat_id LEFT JOIN doctor d ON a.doc_id = d.doc_id ORDER BY appointment_date DESC").fetchall()
return appointment
def post(self):
appointment = request.get_json(force=True)
pat_id = appointment['pat_id']
doc_id = appointment['doc_id']
appointment_date = appointment['appointment_date']
a = conn.execute("SELECT count(*) From appointment WHERE doc_id =?
AND appointment_date=?",(doc_id,appointment_date,)).fetchone()
if a['count(*)'] == 0:
appointment['app_id'] = conn.execute('''INSERT INTO appointment(pat_id,doc_id,appointment_date)VALUES(?,?,?)''', (pat_id, doc_id,appointment_date)).lastrowid
conn.commit()
return appointment
else:
pass
what do I return instead of the pass statement?
PS: For context, I'm trying to improve https://github.com/tushariscoolster/HospitalManagementSystem
Flask-Restful provides an abort function, it's can raise an HTTPException with special HTTP code and message back to the client.
So, you can try to change the code like below:
from flask_restful import abort
class Appointments(Resource):
def post(self):
# ignore some code
if a['count(*)'] == 0:
# ignore some code
else:
abort(403, error_message='just accept an appointment on special date')
then, the client will receive 403 and a valid JSON string like below:
{"error_message":"just accept an appointment on special date"}
The last, the client should deal with the error message properly.
I'm trying to do a simple save string to datastore, redirect on that entity's key, then fetch it in the next handler. When I make the call in PDFHandler to fetch the string (a.name()) "w" is returned everytime, no matter what I enter.
class Pdf(db.Model):
name = db.StringProperty(required=True)
class InputHandler(Handler):
def get(self):
self.render('cert_form.html')
def post(self):
name = self.request.get('name')
if name:
a = Pdf(name=name)
a.put()
self.redirect('/key=%s' % a.key())
else:
error = "Please enter your full name."
self.render('cert_form.html')
class PDFHandler(Handler):
def get(self, id):
a = db.Key.from_path('Pdf', id)
self.response.write(a.name())
application = webapp2.WSGIApplication([
(r'/', InputHandler),
(r'/key=(.)+', PDFHandler),
], debug=True)
In your PDFHandler when you do
a = db.Key.from_path('Pdf', id)
What you are getting is the Key object not the entity yet.
To get the Pdf entity you can do the below
pdf = db.get(a)
Then you can access fields on pdf like pdf.name etc.