I have already looked at this SO question, so far it has not helped.
So I am trying to check if a row exists in a table with Flask-SQLAlchemy, and so far nothing has helped.
My current code:
#app.route('/guilds/<guildid>')
def guildsettings(guildid):
discord = make_session(token=session.get('oauth2_token'))
user = discord.get(API_BASE_URL + '/users/#me').json()
guilds = discord.get(API_BASE_URL + '/users/#me/guilds').json()
row = Settings.query.all()
exists = Settings.query.filter_by(db.exists().where(Settings.guildid==guildid)).scalar()
print(exists)
if exists == True:
info = Settings.query.filter_by(guildid=guildid).first()
return render_template("guild.html", id=guildid, guilds=guilds, User=user, prefix=info.prefix, logschannel=info.logschannel, modrole=info.modrole, adminrole=info.adminrole, welcomechannel=info.welcomechannel, welcomemessage=info.welcomemessage, dadbot=info.dadbot, music=info.music, funcmds=info.funcmds, weather=info.weather, wapikey=info.wapikey)
else:
return render_template("notinserver.html", guildid=guildid, link="https://discordapp.com/api/oauth2/authorize?client_id=xxxxxx&permissions=8&redirect_uri=xxxxxxx%2Fme&scope=bot&guild_id={}".format(guildid))
I am not sure on what to do now. Any help is appreciated.
If it needs to be excactly one result:
try:
Settings.query.filter_by(db.exists().where(Settings.guildid==guildid)).one()
except sqlalchemy.orm.exc.NoResultFound:
return False
except sqlalchemy.orm.exc.MultipleResultsFound:
#do what ever you want to do if there is more than one result
return True
Related
I am trying to generate incremental id whenever I am adding new data in my model. here I am getting the the next number whenever I am adding new data. but If there is no any data in my table its giving me error. 'NoneType' object has no attribute 'tax_id'
Here is my code
views.py
def tax_settings(request):
latest_id = (Tax_Settings.objects.last()).tax_id+1
if request.method == 'POST':
tax_id = latest_id
name = request.POST['tax_name']
tax_percentage = request.POST['tax_percentage']
tax_details=Tax_Settings.objects.create(tax_id=tax_id, name=name, tax_percentage=tax_percentage)
tax_details.save()
next_id = (Tax_Settings.objects.last()).tax_id+1
return render(request,"settings/tax-settings.html",{"latest_id":next_id})
else:
return render(request,"settings/tax-settings.html",{"latest_id":latest_id})
html
<input type="text" class="form-control" placeholder="{{latest_id}}" name="tax_id" disabled>
which condition I can give to my latest_id if data(tax_id) not exists?
You are trying to do too much in too few lines of code. Wherever you use queryset .last() or .first() you must explicitly handle the case where it returns None!
You need code of the form:
o = Tax_Settings.objects.last()
if o is not None:
tax_id = o.tax_id + 1
else:
tax_id = 1 # if that's a sensible default value
or even
o = Tax_Settings.objects.last()
assert o is not None, "This can't happen!" # except obviously, it does in this question.
Either you first create a single record than don't need to handle this or
tax_id = 0
latest_rec = (Tax_Settings.objects.last())
if latest_rec is not None:
latest_id = latest_rec.tax_id+1
You could simply add:
if latest_id is None:
latest_id = 1
If I understand it correctly, you have issues with your first line in the provided function:
latest_id = Tax_Settings.objects.last().tax_id+1
when you have no data, i.e. Tax_Settings.objects.last() is None.
You should define default ID, for instance 0 which would be assigned in case of missing objects:
def tax_settings(request):
if Tax_Settings.objects.last() is not None:
# some data already stored
latest_id = Tax_Settings.objects.last().tax_id
else:
# no data present yet
latest_id = 0
. . .
btw. I am not sure why are you incrementing the latest value in the beginning, but you need to take into account that if your default latest ID is 0 then the ID of the first data unit stored will be 1.
The following code also works:
tax_data=Tax_Settings.objects.all()
if not tax_data:
print("no data found")
latest_id=1
else:
latest_id = (Tax_Settings.objects.last()).tax_id+1
I´m trying to save a SQLAlchemy query result on a python variable (in case there is one result) in order to insert it with other data later. Is there any chance to do something like that?
Things you may want to know:
I'm trying to connect to an Oracle DB
I'm using python 3.7.1
Till now I´ve been able to do this:**
try:
map_projn_id_search = Session.execute("""
SELECT GEOFRAME_MAP_PROJN_ID
FROM V_GEOFRAME_MAP_PROJN
WHERE COORD_REF_SYS_CODE = :crs AND TRNSFRM = :tfm"""
, {"crs" : crs , "tfm" : tfm} )
map_projn_id_search.fetchone()
except Exception as e:
print("error")
else:
#If it doesn´t exist I need to insert it into the V_GEOFRAME_MAP_PROJN
if map_projn_id_search.rowcount == 0:
instances_with_unkown = ['SAMSDB', 'CASSDB', 'CCUSDB', 'EMASDB', 'EMLSDB', 'HNOSDB', 'KULSDB', 'NAFSDB', 'RUSSDB', 'YUZSDB', 'AMESDB', 'LAGSDB']
instances_with_UNKNWON =[ 'USASDB']
if emsdb_instance in instances_with_unkown:
projn_id = "Unknown"
print(f'\n The EPSG code (ProjCRS:GeogCRS:Tfm) does not exist on EMSDB. Set {projn_id} as CRS. \n')
elif emsdb_instance in instances_with_UNKNWON:
projn_id = "UNKNOWN"
print(f'\n The EPSG code (ProjCRS:GeogCRS:Tfm) does not exist on EMSDB. Set {projn_id} as CRS. \n')
else:
#If it exists then print that it exists so the user knows
print("\n Cannot insert the EPSG code (ProjCRS:GeogCRS:Tfm) on that database. \n")
elif map_projn_id_search.rowcount != 0:
#If it exists then print that it exists so the user knows
projn_id = map_projn_id_search.fetchone()
print(f"\n Set {projn_id} as the CRS of the survey. \n")
So, what I needed to do is:
Add a variable like
a = map_projn_id_search.fetchone()
And then make another who could fetch the first result as a string instead of a list
b = a[0]
I use flask, an api and SQLAlchemy with SQLite.
I begin in python and flask and i have problem with the list.
My application work, now i try a news functions.
I need to know if my json informations are in my db.
The function find_current_project_team() get information in the API.
def find_current_project_team():
headers = {"Authorization" : "bearer "+session['token_info']['access_token']}
user = requests.get("https://my.api.com/users/xxxx/", headers = headers)
user = user.json()
ids = [x['id'] for x in user]
return(ids)
I use ids = [x['id'] for x in user] (is the same that) :
ids = []
for x in user:
ids.append(x['id'])
To get ids information. Ids information are id in the api, and i need it.
I have this result :
[2766233, 2766237, 2766256]
I want to check the values ONE by One in my database.
If the values doesn't exist, i want to add it.
If one or all values exists, I want to check and return "impossible sorry, the ids already exists".
For that I write a new function:
def test():
test = find_current_project_team()
for find_team in test:
find_team_db = User.query.filter_by(
login=session['login'], project_session=test
).first()
I have absolutely no idea to how check values one by one.
If someone can help me, thanks you :)
Actually I have this error :
sqlalchemy.exc.InterfaceError: (InterfaceError) Error binding
parameter 1 - probably unsupported type. 'SELECT user.id AS user_id,
user.login AS user_login, user.project_session AS user_project_session
\nFROM user \nWHERE user.login = ? AND user.project_session = ?\n
LIMIT ? OFFSET ?' ('my_tab_login', [2766233, 2766237, 2766256], 1, 0)
It looks to me like you are passing the list directly into the database query:
def test():
test = find_current_project_team()
for find_team in test:
find_team_db = User.query.filter_by(login=session['login'], project_session=test).first()
Instead, you should pass in the ID only:
def test():
test = find_current_project_team()
for find_team in test:
find_team_db = User.query.filter_by(login=session['login'], project_session=find_team).first()
Asides that, I think you can do better with the naming conventions though:
def test():
project_teams = find_current_project_team()
for project_team in project_teams:
project_team_result = User.query.filter_by(login=session['login'], project_session=project_team).first()
All works thanks
My code :
project_teams = find_current_project_team()
for project_team in project_teams:
project_team_result = User.query.filter_by(project_session=project_team).first()
print(project_team_result)
if project_team_result is not None:
print("not none")
else:
project_team_result = User(login=session['login'], project_session=project_team)
db.session.add(project_team_result)
db.session.commit()
I am trying to build a simple web application with 3 web services. Two of my web services are supposed to validate if a student exist in a course or not. This is done by a simple SELECT-query. My third web service should add a student into a database, but only if the student do exist in the specific course.
This is my validation WS which should return a true/false.
#app.route('/checkStudOnCourse/<string:AppCode>/<string:ideal>', methods= ["GET"])
def checkStudOnCourseWS(AppCode, ideal):
myCursor3 = mydb.cursor()
query3 = ("SELECT studentID FROM Ideal.course WHERE applicationCode = " + "'" + AppCode + "' AND Ideal = " + "'" + ideal + "'")
myCursor3.execute(query3)
myresult3 = myCursor3.fetchall()
if len(myresult3) == 0:
return render_template('Invalid.html')
else:
return jsonify({'Student in course ': True})
Below is regResult which should do a SQL insert into a database. I only want the submit to work if the above result is "True", how can I do that? I know I have not done the INSERT query, but that is not a problem.
What I am unsure about is: How can I only let the submit be be INSERTED if the validation WS is "True".
#app.route('/register', methods=["POST", "GET"])
def regResultat():
if request.method == "POST":
Period = request.form['period']
#ProvNr = request.form['provNr']
Grade = request.form['grade']
Applicationcode = request.form['applicationcode']
#Datum = request.form['datum']
Ideal = request.form['ideal']
CheckStudOnCourse = 'http://127.0.0.1:5000/checkAppCodeWS/'+Applicationcode+'/'+Ideal
CheckStudOnResp = requests.get(CheckStudOnCourse)
At first, such syntax:
if len(myresult3) == 0, can be simplified by if myresult3, because Python evaluates that implicitly to bool.
Secondly, if you once returned from function, there is no need to write an else statement:
if len(myresult3) == 0:
return render_template('Invalid.html') # < -- in case 'True',
# it returns here, otherwise
# function keeps going"""
return jsonify({'Student in course ': True}) # < -- in case 'False', it is returned here
Focusing on your issue, you could do that:
Get your value from ws
CheckStudOnCourse = 'http://127.0.0.1:5000/checkAppCodeWS/'+Applicationcode+'/'+Ideal
CheckStudOnResp = requests.get(CheckStudOnCourse)
Extract json from it:
if result_as_json.status == 200:
result_as_json = CheckStudOnResp.json() # < -- it is now a dict
Do some checks:
if result_as_json.get('Student in course', False): # I highly suggest to use other
# convention to name json keys
# e.g. Student in course ->
# student_exists_in_course
# do your code here
I am using the following passage of code:
#app.route('/budget_item/<int:budget_id>/edit', methods=['GET', 'POST'])
def budget_item_edit(budget_id):
budget_item = session.query(Budget).filter_by(id=budget_id).one()
print "Start EDIT sequence"
# Return form data from HTML initial load form
elif request.method == 'POST':
budget_amount_reallocated_total = budget_item.budget_amount_reallocated_total
#ORIGINAL BUDGET
if request.form['transaction_type'] == 'Original Budget':
#amount
if request.form['amount'] == "":
amount = 0
else:
amount = float(str(request.form['amount']))
budget_item = Budget(
#created_date = "",
budget_transaction_type = request.form['transaction_type'],
budget_line = request.form['budget_line'],
amount = amount,
description = request.form['description']
#date_received = request.form['date_received']
)
try:
count = 1
while count < 10000:
count += 1
#budget_line
setattr(budget_item,'budget_line'+str(count),request.form['budget_line'+str(count)])
#amount
setattr(budget_item,'amount'+str(count),float(request.form['amount'+str(count)]))
budget_amount_reallocated_total += float(request.form['amount'+str(count)])
setattr(budget_item, 'budget_amount_reallocated_total', budget_amount_reallocated_total)
#description
setattr(budget_item,'description'+str(count), request.form['description'+str(count)])
#date_received
setattr(budget_item,'date_received'+str(count),request.form['date_received'+str(count)])
session.commit()
except:
session.commit()
return redirect(url_for('budget_master'))
else:
print "I'm done! This is not a post request"
This block of code is setup to pass data from an HTML via a POST request an then update a corresponding object in the Postgres DB. I can confirm that the object queried from the DB "budget_item" is being updated by settattr. At the end of the passage, I use commit() to update the object; however, the database doesn't reflect the changes. Just to test to make sure things are flowing, I've tried session.add(budget_item) followed by session.commit() to make sure the connect to the DB is OK. That works. How do i update this budget_item object into the database? Any help is much appreciated.
i think that a simple
budget_item.budget_amount_reallocated_total = budget_amount_reallocated_total
session.add(budget_item)
session.commit()
is the right way to do it
To answer your question, to update the budget_item that already exists in the database you need to update the Budget instance that you retrieved from the database, i.e.
budget_item = session.query(Budget).filter_by(id=budget_id).one()
not the one that you have newly created with:
budget_item = Budget(...)
Here the first budget_item represents the row in the database, so this is the one to update. To that end you can replace the code that creates the second Budget instance with this:
budget_item.budget_transaction_type = request.form['transaction_type']
budget_item.budget_line = request.form['budget_line']
budget_item.amount = amount
budget_item.description = request.form['description']
Once you have finished updating the Budget instance you can call session.commit() to flush it to the database.
As mentioned in my comment to your question, it appears that you are trying to add a large number of additional attributes to budget_item all of which will be ignored by sqlalchemy unless they are defined in the mapping between the Budget instance and the Budget table.