I need to make query like this:
WHERE Comment like '%ev% 3628%' or Comment like '%ew% 3628%'
the number '3628' is a parametr. So I've tried in my view:
First try:
wherestr = "Comment like '%%ev%% %s%%' or Comment like '%%ew%% %s%%'" % (rev_number, rev_number)
comment_o = Issuecomments.objects.extra(where=[wherestr])
but I've got:
TypeError at /comments_by_rev/3628/
not enough arguments for format string
Request Method: GET
Request URL: http://127.0.0.1:8001/comments_by_rev/3628/
Exception Type: TypeError
Exception Value:
not enough arguments for format string
Second try:
comment = IssuetrackerIssuecomments.objects.filter(Q(comment__contains=rev_number), Q(comment__contains='ew') | Q(comment__contains='ev'))
but its not excactly the same.
Have you people of wisdom any idea how to accomplish this?
You need something similar to this:
from django.db.models import Q
def myview(request):
query = "hi" #string to search for
items = self.filter(Q(comment__contains=query) | Q(comment__contains=query))
...
Just make sure the query string is properly escaped.
You almost got it right... The problem is that your % are being subsituted twice. Django actually has a way of passing parameters in the extra clause like this
wherestr = "Comment like '%%ev%% %s%%' or Comment like '%%ew%% %s%%'"
params = (rev_number, rev_number)
comment_o = Issuecomments.objects.extra(where=[wherestr], params=[params])
This is a better way of passing the parameters as it won't leave you open to SQL injection attacks like your way will.
Take a look at http://docs.djangoproject.com/en/dev/ref/models/querysets/, specifically
icontains: Case-insensitive containment test.
Example: Entry.objects.get(headline__icontains='Lennon')
SQL equivalent: SELECT ... WHERE headline ILIKE '%Lennon%';
Since you're looking for a pattern like %%ev%% or %%ew%%, consider the IREGEX or REGEX versions as well?
Lastly, consider performing the search differently...perhaps parse out the interesting parts of the message and put them in their own indexed columns for querying later. You'll regret doing this search once the table gets large:).
Related
May I know what is wrong with my below code ? I would like to query all where date_occ is between '2015-01-10T12:00:00' and '2015-12-31T24:00:00'
response = requests.get('https://data.lacity.org/api/id/7fvc-faax.json?$select=*&$where = date_occ between 2015-01-10T12:00:00 and 2015-12-131T24:00:00')
I get the following error:
Unrecognized arguments [$where ]
I realise the following doesn't work as well
response = requests.get('https://data.lacity.org/api/id/7fvc-faax.json?$select=*&vict_age >20')
data = response.json()
data = json_normalize(data)
data = pd.DataFrame(data)
But this works:
response = requests.get('https://data.lacity.org/api/id/7fvc-faax.json?$select=*&vict_sex=M')
what am I missing here?
There are a few questions and answers posed in this one. Starting with your second query first; where you want to look at age above 20 years-old. Looking at the metadata (click the down arrow), the victim age is not numeric and is a text string. Thus, you won't be able to use operators like greater than, less than, etc. However, you can look for "equal to". The query below will work:
https://data.lacity.org/resource/7fvc-faax.json?$where=vict_age = '20'
Note: I've dropped the $select and am just using $where for simpler display.
Your third example works since you've set it to query a text field. If you want LA to change it to a numeric, click the "Contact Dataset Owner" under the ellipsis button.
Your first question on dates has a few changes. First, your single quotation marks were not aligned and some were missing. Second, the latter date is 2015-12-131T24:00:00, which has an invalid day. Finally, the data on the portal does not have a timestamp, so you only need the year-month-day. This will work:
https://data.lacity.org/resource/7fvc-faax.json?$where=date_occ between '2015-01-10' and '2015-12-13'
Finally, I would recommend that you use the URL structure, https://data.lacity.org/resource/7fvc-faax.json? instead of /api/id/. The former is the proper URL structure for Socrata-based APIs.
I would like to use a list of int to be used in a query as below:
db.define_table('customer',Field('name'),Field('cusnumber','integer'))
def custmr():
listOfNumbers=[22,12,76,98]
qry=db(db.customer.cusnumber==listOfNumbers).select(db.customer.name)
print qry
this arise an issue that the only accepted data type in the query is int or str.
Is there any way to avoid this issue (preferably by not using for loop)
Regards
It is really difficult to know what you're trying to ask, but from the syntax of db.define_table(...), I take a wild guess you're on web2py and trying to do a query which fetch any int in your listOfNumbers.
You may use contains attribute like this:
# if all=True, cusnumber will need to contains all listOfNumbers, False means any
qry=db(db.customer.cusnumber.contains(listOfNumbers, all=False)).select(db.customer.name)
You can read more in details in HERE
As OP replied that contains only works for string, I'm going to suggest using for/loop will be a better answer:
listOfNumbers=[22,12,76,98]
for each in listOfNumbers:
qry=db(db.customer.cusnumber==each).select(db.customer.name)
# ... do your stuff or whatever ...
Assuming you want the set of records for which the cusnumber is in listOfNumbers, you should use the .belongs method:
qry = db(db.customer.cusnumber.belongs(listOfNumbers)).select(db.customer.name)
I'm developing application using Bottle. How do I get full query string when I get a GET Request.
I dont want to catch using individual parameters like:
param_a = request.GET.get("a","")
as I dont want to fix number of parameters in the URL.
How to get full query string of requested url
You can use the attribute request.query_string to get the whole query string.
Use request.query or request.query.getall(key) if you have more than one value for a single key.
For eg., request.query.a will return you the param_a you wanted. request.query.b will return the parameter for b and so on.
If you only want the query string alone, you can use #halex's answer.
I am implementing a one off data importer where I need to search for existing slugs. The slugs are in an array. What is the accepted best practices way of converting an array to an OR query?
I came up with the following, which works, but feels like way too much code to accomplish something this simple.
# slug might be an array or just a string
# ex:
slug = [ "snakes", "snake-s" ] # in the real world this is generated from directory structure on disk
# build the query
query = MyModel.objects
if hasattr(slug, "__iter__"):
q = Q()
for s in slug:
q = q.__or__(Q(slug=s))
query = query.filter(q)
else:
query = query.filter(slug=slug)
slug = ["snakes", "snake-s" ] # in the real world this is generated from directory structure on disk
# build the query
query = MyModel.objects
if hasattr(slug, "__iter__"):
q_list = []
for s in slug:
q_list.append(Q(slug=s))
query = query.filter(reduce(operator.or_, q_list))
else:
query = query.filter(slug=slug)
q_list = [] create a list of Q clauses
reduce(operator.or_, q_list) implode the list with or operators
read this: http://www.michelepasin.org/techblog/2010/07/20/the-power-of-djangos-q-objects/
#MostafaR - sure we could crush my entire codeblock down to one line if we wanted (see below). Its not very readable anymore at that level though. saying code isn't "Pythonic" just because it hadn't become reduced and obsfucated is silly. Readable code is king IMHO. Its also important to keep in mind the purpose of my answer was to show the reduce by an operator technique. The rest of my answer was fluff to show that technique in context to the original question.
result = MyModel.objects.filter(reduce(operator.or_, [Q(slug=s) for s in slug])) if hasattr(slug, "__iter__") else MyModel.objects.filter(slug=slug)
result = MyModel.objects.filter(slug__in=slug).all() if isinstance(slug, list) else MyModel.objects.filter(slug=slug).all()
I believe in this case you should use django's __in field lookup like this:
slugs = [ "snakes", "snake-s" ]
objects = MyModel.objects.filter(slug__in=slugs)
The code that you posted will not work in many ways (but I am not sure if it should be more pseudocode?), but from what I understand, this might help:
MyModel.objects.filter(slug__in=slug)
should do the job.
I am able to properly pass a string variable to the gqlquery through parameter substitution, here's the code i've tried to use;
user_name = self.request.get('username') #retrieved from UI
p = models.UserDetails.all().filter('user_name = ', user_name).fetch(1)
I don't get any results and the query fails silently. But when I hard code the query like this ,
p = models.UserDetails.all().filter('user_name = ', "peter rice").fetch(1)
I get my expected resultset. I think I am passing the variable user_name in a wrong way, Please help me in getting my piece of code right.
Have you tried filter('user_name = ', str(user_name)) ?
I supose you are sure user_name has the expected content.
I think I've got it, I tried using this,
p = models.UserDetails.gql('WHERE user_name = :uname', uname = user_name).fetch(1)
and I got the expected resultset. I wonder why other formats have the problem in string substitution.
Try logging repr(user_name) to verify that the string is exactly the same as what you're expecting (and that it's not unicode rather than raw). Also try logging the expression user_name == "peter rice". Other than that, I can't see any reason why it would not work - there's literally no way the API can affect this, since it doesn't know where the argument you pass in comes from.