I am running a query based off of other ids for the query. The problem i have is that sometimes the query won't find a result. Instead of having the entire program crash, how can I check to see if the result will be None?
This is the query I have:
sub_report_id = DBSession.query(TSubReport.ixSubReport).filter(and_(TSubReport.ixSection==sectionID[0], TSubReport.ixReport== reportID[0])).one()
When the code gets executed and no results are found, I get a NoResultFound exception
NoResultFound: No row was found for one()
is there a way to just skip the query if there is not going to be a result?
Found the solution on SO(couldn't find it before)
Getting first row from sqlalchemy
Use first() function instead of one(). It will return None if there is no results.
sub_report_id = DBSession.query(TSubReport.ixSubReport).filter(and_(TSubReport.ixSection==sectionID[0], TSubReport.ixReport== reportID[0])).first()
see documentation here
You can also use one_or_none(), this returns None when there's no result found and is syntactically clearer than first(). No error handling required.
ref: one_or_none()
How would SQLAlchemy know there wasn't going to be a result without doing the query?
You should catch the exception and handle it then:
from sqlalchemy.orm.exc import NoResultFound
try:
sub_report_id = DBSession.query(TSubReport.ixSubReport).filter(and_(TSubReport.ixSection==sectionID[0], TSubReport.ixReport== reportID[0])).one()
except NoResultFound:
sub_report_id = [] # or however you need to handle it
Related
Given this partial function (and Python 2.7, mysql-connector 2.1.6):
def get_target_item(self, query, key):
self._target_query.execute(query, (key,))
if self._target_query.with_rows:
raw_item = self._target_query.fetchone()
I expected raw_item to always be non-None, but it turns out that it is sometimes None.
If I add this:
if not raw_item:
print "Could not find find target item for query {0} and key {1}".format( query, key )
I can see this gets printed sometimes. And if I run the same query myself, I can see that the query does not return rows for the specified key. So why does with_rows suggest that it does?
The following is what the documentation for .with_rowssays:
Returns whether the cursor could have rows returned
This property returns True when column descriptions are available and
possibly also rows, which will need to be fetched.
As you can see, as long as the description attribute of the cursor is not None, with_rows will return True.
If you are using a buffered cursor, you can check the cursor's rowcount attribute to make sure that it is greater than 0. That should constitute a better check.
I hope this proves useful.
Lets consider I am trying to find if a user with primary key 20 exists or not? I can do this in 2 ways.
The First one :
try:
user = User.objects.get(pk=20)
except User.DoesNotExist:
handle_non_existent_user()
The other way could be :
users = User.objects.filter(pk=20)
if not users.exists():
handle_non_existent_user()
Which is better method to do check existence?
This might be related to this : What is the best way to check if data is present in django?
However, people favoured the first method because of specified examples did not had the reference of model queryset.
Also in the answer of following question : what is the right way to validate if an object exists in a django view without returning 404?
It is largely based because we are not getting the reference of object in question.
TLDR: For cases when you almost always sure that the object is db it is better to use try:get for cases when there is 50% chance that object doesn't exists then it is better to use if:filter.exists
It really depends on code context. For example there are cases when if statement is better than try/except Using try vs if in python
So for your question it is the same Difference between Django's filter() and get() methods. get method underneath calls filter
https://github.com/django/django/blob/stable/1.11.x/django/db/models/query.py#L366
def get(self, *args, **kwargs):
"""
Performs the query and returns a single object matching the given
keyword arguments.
"""
clone = self.filter(*args, **kwargs)
if self.query.can_filter() and not self.query.distinct_fields:
clone = clone.order_by()
num = len(clone)
if num == 1:
return clone._result_cache[0]
if not num:
raise self.model.DoesNotExist(
"%s matching query does not exist." %
self.model._meta.object_name
)
raise self.model.MultipleObjectsReturned(
"get() returned more than one %s -- it returned %s!" %
(self.model._meta.object_name, num)
)
So in case when you use filter with exists. It will do almost the same code because exists underneath does this
def exists(self):
if self._result_cache is None:
return self.query.has_results(using=self.db)
return bool(self._result_cache)
And as you can see filter.exists will execute less code and should work faster, but it doesn't return you an object.
The first one is the best way in my opinion because if I ever forget to check whether the user exists or not, it will give me an error even if I don't use the try / except clause.
Also, get was made specifically to get ONE item only.
I have some questions about django exists() and DoesNotExist exception.
Example code:
id = 1
# first
if User.objects.get(pk=id).exists():
# my logic
pass
# second
try:
User.objects.get(pk=id)
# my logic
pass
except User.DoesNotExist:
return 0
I often use get() method. Which practice is better? Which code is better? The first or second?
if User.objects.get(pk=id).exists()
This won't work, so the question is pretty easy to answer: This way is inferior to the ways which do work :-)
I guess you actually didn't make a Minimal Complete Verifiable Example and so missed the error when you posted un-verified code.
So instead, I suppose you are asking about the difference between:
QuerySet.exists() when you have a QuerySet (e.g. from a filter operation).
For example:
if User.objects.filter(pk=id).exists():
# ... do the things that need that user to exist
Model.objects.get(…) and catching the Model.DoesNotExist exception type (or, if you want to be more general, the parent type ObjectDoesNotExist).
For example:
try:
user = User.objects.get(pk=id)
except User.DoesNotExist:
# ... handle the case of that user not existing
The difference is:
The QuerySet.exists method is on a queryset, meaning you ask it about a query (“are there any instances matching this query?”), and you're not yet attempting to retrieve any specific instance.
The DoesNotExist exception for a model is raised when you actually attempted to retrieve one instance, and it didn't exist.
Use whichever one correctly expresses your intention.
You can find more info in docs:
about exists(),but exists() works only for QuerySet
Returns True if the QuerySet contains any results, and False if not. This tries to perform the query in the simplest and fastest way possible, but it does execute nearly the same query as a normal QuerySet query.
exists() is useful for searches relating to both object membership in a QuerySet and to the existence of any objects in a QuerySet, particularly in the context of a large QuerySet.
But ObjectDoesNotExist works only with get().
Also you can try another approach:
user = User.objects.filter(id=2)
if user:
# put your logic
pass
Since we are in Django, we'll try to catch the error with Django functionality instead of the common way(which is using Exceptions with Python).
id = 1
def a_query(id):
qs = User.objects.filter(pk=id)
if qs.exists():
return qs.first()
return None
In here, the method exists() helps you catching the error(if there's any).
ref: https://docs.djangoproject.com/en/3.0/ref/models/querysets/#django.db.models.query.QuerySet.exists
in django model,
if you gonna use model.objects.get() if it wasn't exist it raise an error. in that case you can use DoesNotExist along with except:
try:
val = Model.objects.get(pk=val) # if nothing found it will raise an exception
exception:
you can trace an exception without mentioning anything on top.
(or)
exception ObjectDoesNotExist:
# it will come here if exception is DoesNotExist
For Django version 2.0.6, you can do the following, and it will work:
if Model.objects.filter(my_id=objectid).exists():
myobject = get_object_or_404(Model, my_id=objectid)
context = {'myobject': myobject}
return render(request, self.template_name, context)
You can get more info here: https://docs.djangoproject.com/en/2.1/ref/models/querysets/
It's my understanding that you're asking whether to use if statements or try catch on your code. I personally prefer to avoid using try catch, a think it's an ugly syntax, when I do want to raise an exception, I use a python keyword raise, to me, it makes the code cleaner.
Code example:
user = User.objects.filter(id=2)
if not user:
raise ObjectDoesNotExist
I am on the following cx_Oracle version
>>> cx_Oracle.version
'5.0.3'
I am getting this exception in executing a query
"expecting None or a string"
The query is being executed this way
cursor.execute("SELECT * FROM APP_STORE WHERE STORE=:STORE %s" %(order_clause),{'STORE':STORE})
What could be the reason? Similar queries executed earlier in the flow work fine but this one does not.
Appreciate some guidance on this.
You are building your cursor incorrectly. Since you pass a dictionary, you much first prepare your query:
cursor.prepare("SELECT * FROM APP_STORE WHERE STORE=:STORE %s" %(order_clause))
Then you execute it and pass None as the first parameter.
results = cursor.execute(None, {'STORE':STORE})
If you wish to change the STORE parameter and run the query again, all you need to do now is modify the dictionary and rerun the execute statement. prepareing it again is not needed.
More information can be found at the Oracle+Python Querying best practices documentation. The information I provided, above, is in the "Bind Variable Patterns" section (no direct link seems to be available)
There is probably a better way of dealing with non existant query sets...!
The problem i have with this code is that it raises an exception if the normal case will be true! That is: if a workspace name with the same name in the db is not existent.
But instead of having an exception i would like to go for a query that does not return DoesNotExist but true or false
My unelegant code:
try:
is_workspace_name = Workspace.objects.get(workspace_name=workspace_name,user=self.user.id )
except:
return workspace_name
if is_workspace_name:
raise forms.ValidationError(u'%s already exists as a workspace name! Please choose a different one!' %workspace_name )
Thanks a lot!
You can use exists() method. Quoting docs:
Returns True if the QuerySet contains any results, and False if not.
This tries to perform the query in the simplest and fastest way
possible, but it does execute nearly the same query as a normal
QuerySet query.
Remarks: the simplest and fastest way. It is cheaper to use exists (than count) because with exists the database stops counting at first occurrence.
if Workspace.objects.filter(workspace_name=workspace_name,
user=self.user.id).exists()
raise forms.ValidationError(u'%s already exists ...!' % workspace_name)
else:
return workspace_name
Checking for the existence of a record.
If you want to test for the existence of a record in your database, you could be using Workspace.objects.filter(workspace_name = workspace_name,user = self.user.id).count().
This will return the number of records matching your conditions. This number will be 0 in case there is none, which will be readily usable with an if clause. I believe this to me the most standard and easy way to do what you need here.
## EDIT ## Actually that's false, you might want to check danihp's answer for a better solution using Queryset.exists!
A word of warning: the case of checking for existence before insertion
Be cautious when using such a construct however, especially if you plan on checking whether you have a duplicate before trying to insert a record. In such a case, the best solution is to try to create the record and see if it raises an exception.
Indeed, you could be in the following situation:
Request 1 reaches the server
Request 2 reaches the server
Check is done for request 1, no object exist.
Check is done for request 2, no object exist.
Proceed with creation in request 1.
Proceed with creation in request 2.
And... you have a duplicate - this is called a race condition, and is a common issue when dealing with parallel code.
Long story short, you should use try, expect and unique constraints when dealing with insertion.
Using get_or_create, as suggested by init3, also helps. Indeed, get_or_create is aware of this, and you'll be safe so long as unwanted duplicated would raise an IntegrityError
obj, created = Workspace.objects.get_or_create(workspace_name=workspace_name, user=self.user.id)
if created:
# everything ok
# do something
pass
else:
# not ok
# respond he should choose anything else
pass
read more at the docs