Raw SQL in Django - mysql

I am try to perform a RAW SQL query in django. I am having some trouble getting the fetchall result to output a list of the distinct items in a column.
So I am hoping to get a list of all the items in a column.
class TableObject (object):
def __init__ (self, Kingdom):
SQL_str_Table = "SELECT DISTINCT column_title FROM sql_table"
cursor.execute(SQL_str_Table, [])
listOfReturns = cursor.fetchall()
for each in listOfReturns:
item = each
when I try a print out of "item" I get:
"bound method TableObject.write of mysite.forms.veiws.TableObject object at 0x03E5EE70"
So my question is how do I get the fetchall result into a list.

If you want to get a flat list of only column_title's then you can do this:
listOfReturns = cursor.fetchall()
listOfReturns_flat = [i for i in listOfReturns if i[0]] #remove empty results if any

Related

for loop in API call returns same result in each loop

I have written a loop to retrieve data from an API (Limesurvey) based on a list of ids and fill a row of a dataframe with the result of each loop.
I have a list with ids like this:
# list of ids
ids = ['1','427',... ,'847']
My code to query the API based on each item of the list looks as follows:
method = "get_participant_properties"
params = OrderedDict([
("sSessionKey", api.session_key),
("iSurveyID", 12345),
("aTokenQueryProperties", t),
])
# loop through API query with the 'aTokenQueryProperties' stored in the list 'tids'.
attributes = []
for t in ids:
attributes.append(api.query(method=method, params=params))
pd.DataFrame(attributes)
Unfortunately, the result is a dataframe with 158 rows, and each row is the same, i.e. the query result of the last id in my list (847).
You are not passing in the t from the loop. The t in the params definition is unrelated; if I were to run your code now I'd get a NameError exception because t hasn't been set at that point. The t expression in the params mapping is not live, it is not updated each loop iteration.
Set the 'aTokenQueryProperties' key in the loop:
method = "get_participant_properties"
params = OrderedDict([
("sSessionKey", api.session_key),
("iSurveyID", 12345),
("aTokenQueryProperties", None),
])
attributes = []
for t in ids:
params["aTokenQueryProperties"] = t
attributes.append(api.query(method=method, params=params))
Setting "aTokenQueryProperties" to None in the params OrderedDict object at the start is optional; you'd only need to do this if reserving its exact location in the params order is important and even then, because in your example it is the last element in the mapping, you'd end up with the same output anyway.

How can I use Django.db.models Q module to query multiple lines of user input text data

How would I go about using the django.db.models Q module to query multiple lines of input from a list of data using a <textarea> html input field? I can query single objects just fine using a normal html <input> field. I've tried using the same code as my input field, except when requesting the input data, I attempt to split the lines like so:
def search_list(request):
template = 'search_result.html'
query = request.GET.get('q').split('\n')
for each in query:
if each:
results = Product.objects.filter(Q(name__icontains=each))
This did not work of course. My code to query one line of data (that works) is like this:
def search(request):
template = 'search_result.html'
query = request.GET.get('q')
if query:
results = Product.objects.filter(Q(name__icontains=query))
I basically just want to search my database for a list of data users input into a list, and return all of those results with one query. Your help would be much appreciated. Thanks.
Based on your comments, you want to implement OR-logic for the given q string.
We can create such Q object by reduce-ing a list of Q objects that each specify a Q(name__icontains=...) constraint. We reduce this with a "logical or" (a pipe in Python |), like:
from django.db.models import Q
from functools import reduce
from operator import or_
def search_list(request):
template = 'search_result.html'
results = Product.objects.all()
error = None
query = request.GET.get('q')
if query:
query = query.split('\n')
else:
error = 'No query specified'
if query:
results = results.filter(
reduce(or_, (Q(name__icontains=itm.strip()) for itm in query))
)
elif not error:
error = 'Empty query'
some_context = {
'results' : results,
'error': error
}
return render(request, 'app/some_template.html', some_context)
Here we thus first check if q exists and is not the empty string. If that is the case, the error is 'No query specified'. In case there is a query, we split that query, next we check if there is at least one element in the query. If not, our error is 'Empty query' (note that this can not happen with an ordinary .split('\n'), but perhaps you postprocess the list, and for example remove the empty elements).
In case there are elements in query, we perform the reduce(..) function, and thus filter the Products.
Finally here we return a render(..)ed response with some_template.html, and a context that here contains the error, and the result.

Object.get() is not iterable

I have this view
def view_involved_people(request):
schedule = request.POST['schedule']
query = Schedule.objects.get(pk=schedule)
serialized = serializers.serialize('json', query)
data = {'people': serialized}
return JsonResponse(data)
It displays that the object is not iterable. I think it is because I am only getting one instance of the object. However, how can I prevent this error and get this data from the view?
I have tried using .filter() but when I call data.attribute_name, it does not display the value
You have to use filter in you case:
def view_involved_people(request):
schedule = request.POST['schedule']
query = Schedule.objects.filter(pk=schedule)
serialized = serializers.serialize('json', query)
data = {'people': serialized}
return JsonResponse(data)

keyword search in string from mysql using python?

I am pulling from a mysql database table using python3.4. I use the csv module to write the rows of data from the database into .CSV format. Now I am trying toros figure out how I can vet the rows of data by keywords that may show up in the fourth column of data (row[3]). I was thinking of using the re moduleas below but I keep getting errors. Is it not possible to search keywords in a field that is string type and to filter those results if they have those keywords? I keep getting an error. Please help
import re
import csv
userdate = input('What date do you want to look at?')
query = ("SELECT *FROM sometable WHERE timestamp LIKE %s", userdate)
keywords = 'apples', 'bananas', 'cocoa'
# Execute sql Query
cursor.execute(query)
result = cursor.fetchall()
#Reads a CSV file and return it as a list of rows
def read_csv_file(filename):
"""Reads a CSV file and return it as a list of rows."""
for row in csv.reader(open(filename)):
data.append(row)
return data
f = open(path_in + data_file)
read_it = read_csv_file(path_in + data_file)
with open('file.csv', 'wb') as csvfile:
spamwriter = csv.writer(csvfile, delimiter=' ',
quotechar='|', quoting=csv.QUOTE_MINIMAL)
for row in data:
match = re.search('keywords, read_it)
if match:
spamwriter.writerow(row)
I gave up on the regular expressions and used
for row in data:
found_it = row.find(keywords)
if found_it != -1:
spamwriter.writerow(row)

Use HttpResponse with JSON data in this code

This code seems to work fine when I used Django console and just print it.
reference = FloodHazard.objects.filter(hazard='High')
ids = reference.values_list('id', flat=True)
for myid in ids:
getgeom = FloodHazard.objects.get(id=myid).geom
response = BuildingStructure.objects.filter(geom__intersects=getgeom).values(
'brgy_locat').annotate(counthigh=Count('brgy_locat'))
print response
I was able to show all the values, but when using HttpResponse, it returns an empty set. What is the proper way of returning JSON data from a queryset? So far, tried this:
reference = FloodHazard.objects.filter(hazard='High')
ids = reference.values_list('id', flat=True)
response = {}
for myid in ids:
getgeom = FloodHazard.objects.get(id=myid).geom
response['high'] = BuildingStructure.objects.filter(geom__intersects=getgeom).values(
'brgy_locat').annotate(counthigh=Count('brgy_locat'))
json_post = ujson.dumps(list(response))
return HttpResponse(json_post, content_type='application/json')
There is no much sense in your code. You assign all querysets to the single key in the response dict. You should use a list for this purpose:
As far as I understand the code should be something like this:
response = []
for myid in ids:
getgeom = FloodHazard.objects.get(id=myid).geom
response.extend(BuildingStructure.objects.filter(geom__intersects=getgeom)
.values('brgy_locat')
.annotate(counthigh=Count('brgy_locat')))
json_post = ujson.dumps(response)
If you want to return a hazard level as well as the list of buildings then you can return a dict:
json_post = ujson.dumps({'hazard': 'high', 'buildings': response})