I want to create a for loop in dbt that loops through two columns of a table in my database and created case when statements using the values in each row of the two columns. Just like this:
{% set locations = {'%United-States%':'United States', '%USA%':'United States'} %}
select
case
{% for feeder, correct in locations.items() %}
when lower(locationname) like {{feeder}} then {{correct}}
{% endfor %}
end as city
from table
I was able to create lists for both feeder and correct, but I am not able to merge them as key-value pairs of a dictionary to loop through it. Any ideas on how should I do this?
Sounds like you have two problems:
fetch data from another table, and
use that data to populate a case when statement.
Big thing to remember is that the main thing that dbt-jinja does is create a string of SQL. That said, there is clever functionality that lets you query a database before jinja starts to put the string together.
The idea being:
fetch the values from the database that you want to have included in your SELECT query
populate the previously fetched values into the query while rendering the statement
there's two macros that may be of use in the first step:
run_query() (docs), and
dbt-utils' get_query_results_as_dict() (docs)
Something like this might work (provided you already have dbt-utils installed:
{% set locations_query %}
select feeder, correct from my_other_table
{% endset %}
{% set locations = run_query(locations_query) %}
select
case
-- not sure how this part will work yet....
{% for feeder, correct in locations.items() %}
when lower(locationname) like {{feeder}} then {{correct}}
{% endfor %}
end as city
from table
Related
I'm new to django, and i want to show field that related to foreign key in another table. this is the table.
i want to career table got the career_tag_name and hex_code from table color.
i've tried the Career.objects.raw()
this is the query in views.py:
careers = Career.objects.raw('''SELECT website_career_tag.career_tag_name,website_color.hex_code, website_career.*
from website_career INNER JOIN website_career_tag on website_career_tag.id = website_career.career_tag_id_id
LEFT JOIN website_color on website_career_tag.color_id_id = website_color.ID''')
it works perfectly, until i want to use filter() by career_tag_name. when i use query set it's more easy than make it raw to filter.
how do i make those raw query to query set?
It's always better to use django's own ORM rather than raw query and it's quite easy as well. Django querysets always stores all related table informations everywhere, you should just reference to them from the object. For example for career list view you can get all career informations and select the related fields to make loops less expensive in templates:
careers = Career.objects.select_related('career_tag_id', 'career_tag_id__color_id')
And then in a template just refer to related objects as:
{% for career in careers %}
{{ career.career_tag_id.career_tag_name }}
{{ career.career_tag_id.color_id.color_name }}
{% endfor %}
sir I am trying to send multiple rows from a database containing multiple columns. Data is sent successfully to the HTML template in Django but when I tried to print particular columns of rows sent, data is not showing up. please help?
[
Hard to say without knowing what sort of data 'row' contains, is it a list containing dictionaries? I can see you create a list called 'l' which is then not used, it looks like you are trying to target the data you need with this list.
Without knowing what sort of data you have collected I would try in views;
return render(request,'searchresults.html',{"l":l})
Then in your template
<table>
{% for i in l %}
<tr>
<td>1.</td>
<td>{{ i }}
</tr>
{% endfor %}
</table>
In a Django template, I'm iterating over a set of photos, and displaying them one by one. Specifically, right now I just have one photo set, containing 6 objects. I display these 6 objects like so:
{% for pic in picstream.photo_set.all reversed %}
<img src="{{ pic.image_file.url }}"></img>
{% endfor %}
Adding reversed to the statement gives me the 6 objects in the desired ordering (i.e. the latest ids first).
Next, I want to display not more than 4 objects from the photo_set. I added |slice:":4" to picstream.photo_set.all to achieve this. Problem is, it's cutting off the first two objects from my desired oredering.
It seems there ought to have been a way to reverse the list first, and slice later? Need a simple way to do this, without performance compromises.
Instead of using the reversed argument for the for template tag, you can use the reverse method of the queryset itself:
{% for pic in picstream.photo_set.all.reverse|slice:":4" %}
<img src="{{ pic.image_file.url }}"></img>
{% endfor %}
If you are evaluating the original (non-reversed) queryset somewhere else in your code then this will result in a second query hitting the database. If this is the case then you are better off moving the logic into your view code itself or into a template tag.
I've got a model class, House, with several columns. I want to get all the entries to this table, with all the columns, and display these on in a table in a template.
Firstly, how do I pull all the information that I need out of the database (and into a 2d list?), and what tag could I use to access specific data in the table?
it's as easy as stated here
so, practically:
all_houses = Houses.objects.all()
will give you all the entries in your database.
from within a view, pass that variable to the template context then, in the template:
{% for house in all_houses %}
{{ house.<column_name> }}
{% endfor %}
let me explain this bit of code: once you pass all your entries to the template, you can loop them with {% for %}
{{ house. }} means that you can extract the value you need from the column you need ( column_name ) and place it wherever you want (from whitin the for loop, obviously) so you can have (for example) {{ house.price }}, {{ house.bathrooms }} and so on, for each entry you have in your "all_entries"
I want to list the number of items for each list. How can I find this number in a single query, rather than a query for each list?
Here is a simplified version of my current template code:
{% for list in lists %}
<li>
{{ listname }}:
{% with list.num_items as item_count %}
{{ item_count }} item{{ item_count|pluralize }}
{% endwith %}
</li>
{% endfor %}
lists is passed as: List.objects.filter(user=user)
and num_items is a property of the List model:
def _get_num_items(self):
return self.item_set.filter(archived=False).count()
num_items = property(_get_num_items)
This queries SELECT COUNT(*) FROM "my_app_item" WHERE... n times, where n is the number of lists. Is it possible to make a single query here?
You should do this in your view and send the dictionary, instead.
Model.objects.values_list('item').annotate(Count('num_items'))
This will produce the SQL same as, (or equivalent to) the one you have posted.
In the following, I tried to take into account all your constraints: filtering on fields of List, on fields of Item, counting items , and grouping by list.
The solution I see is that you could use values() (here is the django doc about this : http://docs.djangoproject.com/en/dev/topics/db/aggregation/#values)
from django.db.models import Count
lists = list(List.objects.filter(user=user))
items=Item.objects.values(list).filter(archived=False,list__in=lists).annotate(count=Count("id"))
#you will get a list of dicts of the form [{'count':2,'list':5},...] where 5 is the id of the list
#now, you can match you list with you item counts in python
list_items_count_dict={}
for item in items:
list_items_count_dict[item['list']]=item['count']
for list in lists :
list.item_count = list_items_count_dict.get(list.id)
That will make only 2 queries, one for getting the lists, the other for computing the item counts. Afterwards, you will have two loops (that could probably be replaced by list comprehension one-liners ), but only for the lists you are interested in.
afterwards, in your template, you can use
{{list.item_count}}
There might be a more elegant option, but that is what I have found right now. I am also certain that you could reduce the number of query to one by using custom sql.
Disclaimer: I have not tested this code, but I have tested similar code on similar models. You could have problems because list is one of the keyword of the Python language.