How to use a variable concatenated with a string in dbt_utils.dateadd in dbt? - jinja2

I have set a variable called year.
I want to use dateadd function but instead of using the from_date_or_timestamp like the following example
{{ dbt_utils.dateadd(datepart='day', interval=1, from_date_or_timestamp="'2017-01-01'") }}
I want to use the variable year concatenated with the month and the day, something like this
{{ dbt_utils.dateadd(datepart='day', interval=1, from_date_or_timestamp= year ~ '-01-01') }}
But I can't get this to work... Can anyone help me?

A workaround to this could be the following:
{% set year = 2021 %}
select
{{ dbt_utils.dateadd(
datepart = 'day',
interval = 1,
from_date_or_timestamp = "'" ~ year ~ "-01-01'"
)
}} as date_add_field
Since you need the input of from_date_or_timestamp to be a string, adding a trailing ' and then -01-01', both wrapped in "", you will make it work. The compiled SQL will look like the following (I am using Snowflake, your compiled SQL might defer):
select
dateadd(day, 1, '2021-01-01') as date_add_field

Related

Error Code: list indices must be integers or slices, not str

I have the following code for converting datetime in a json file to the desired format (%Y-%m-%d), but it gave me the error code of " list indices must be integers or slices, not str", highlighting the tweet["created_at"] part.
counts = {}
for tweet in tweet_list:
date = datetime.strftime(datetime.strptime(tweet["created_at"],'%a %b %d %H:%M:%S +0000 %Y'), '%Y-%m-%d')
if date not in counts:
counts[date] = dict(sentiments=list(), tweet_count = 0)
counts[date]["tweet_count"] += 1
full_text = cleanTxt(tweet["text"])
counts[date]["sentiments"].append(find_sentiment(text))
The tweet_list looks like this, I suspect when I converted the dataframe into json using orient='records', it kind of messed up the formatting?
To work around this, I tired using orient = 'index' but the final json file will include the row number and can't get ride of it.

filter string only contains q in mysql

I need help in mysql query, i written this query
select * from post where content REGEXP '^q'
this query is working but it also includes spaces in filter, what i want to do if any content string like "qqqqqq" or "qqqq" or "qqq" or "qq" or "q" for this string only it should have to filter, right now what is happening if i have string like "qqqq qq" then also it is giving me the result, it should not consider that space, can anyone please help me to resolve this issue ?
You can fix your regexp like next:
select * from post where content REGEXP '^q+$';
This regular expression mean the string starts with q and contain only 1 or more q symbols till end of string
Test it on SQLize.online
Try Using this ^q+(?![\s])+$ Regular Expression.
Above RegExp will check for string starting with q and without space.
You don't really need a regex for this. String functions are likely to be more efficient. You can replace all "q"s with empty strings, and ensure that that resulting string is empty:
select * from post where replace(content, 'q', '') = ''
Note that this also allows the empty string. If you want to avoid that, then:
select * from post where content <> '' and replace(content, 'q', '') = ''

Fetching content order by multiple columns

Documentation: https://docs.bolt.cm/content-fetching#ordering-results
I'm trying to fetch a set of records and order them based on two fields. I have created the following request to do so:
{% setcontent records = 'artists' where { gender: 'Male' } orderby 'surname, title ASC' %}
This works fine when using bolt.db as the database but in MySQL it does not. I have the feeling that I have done something similar to this before so I'm wondering if it's version change related. This implementation is using v1.6.5.
OK I've got this working with a quick fix.
What I've done is modified the Storage.php file ever so slightly.
private function getEscapedSortorder($name, $prefix = 'r')
{
// HACK: multiple sort columns
if (strpos($name, ',') !== FALSE) {
return $name;
}
// END HACK: multiple sort columns
list ($name, $asc) = $this->getSortOrder($name);
...
In my contenttypes I can now define sort: surname, title which will automatically do the ASC order, or I could do sort: surname DESC, title ASC or whatever SQL will allow really.
This could easily be modified to handle -surname, -title, etc.
I've not tested this but the usual syntax for MySQL would be:
order surname ASC, title ASC
try tweaking the orderby string to be the same format and see if that does the job.

Trying to make a Django / Mezzanine "Page last updated by on date"

I'm trying to make a "page last updated by (username)" on (date)" line at the bottom of my mezzanine site page. I've successfully got the date part with the syntax:
{{ page.updated|date:"M d, Y" }}
but the username seems more complicated. I have a nice list in django_admin_log containing action_time, user_id and object_id and I can access & display object_id from within my template using {{ page.id }}.
The username is in auth_user and in days of old I would have put in some SQL with a nice table join on user_id to retrieve this information and display it.
I can't seem to get the syntax right - this kind of thing looked promising:
page.objects.raw("select id, title from page")
but no matter how I try to massage it into my base.html with {{ xxx }} or {% xxx %}, I always seem to get an error.
Thanks for any pointers
I've found a way to do this:
I created a custom tag, saved in /appname/templatetags/appname_tags.py, code as follows:
from django import template
from django.db import connection
register = template.Library()
#register.inclusion_tag(‘appname/_updated_by.html')
def updated_by(pageid):
cursor = connection.cursor()
cursor.execute('select user_id from django_admin_log where object_id = %s order by id desc limit 1', [pageid])
userid_set = cursor.fetchone()
userid = userid_set[0]
cursor.execute('select first_name, last_name from auth_user where id = %s', [userid])
username = cursor.fetchone()
return {'first_name': username[0],'last_name': username[1]}
This tag gets rendered via /appname/templates/appname/_updated_by.html, which simply contains:
{{ first_name }} {{ last_name }}
The whole thing then gets called from base.html via this code:
{% load appname_tags %}
And then add at the appropriate point:
Page Last Updated: {{ page.updated|date:"d/n/Y" }} by {% updated_by page.id %}
Hope this helps somebody, I'd be interested to hear if there's an easier / more elegant way to do this!
You should use the LogEntry model[1].
I would probably make a custom context processor[2] that get's the request's
Page, finds the newest LogEntry for the Page instance and adds updated_on
and updated_by context variables.
[1] https://github.com/django/django/blob/master/django/contrib/admin/models.py#L27
[2] https://docs.djangoproject.com/en/dev/ref/templates/api/#writing-your-own-context-processors

Extract a search string in context

I'm trying to do a MySQL query where I extract the search string in context. So if the search is "mysql" I'd like to return something like this from the 'body' column
"It only takes minutes from downloading the MySQL Installer to having a ready to use"
This is what I've got now but it doesn't work because it just grabs the first 20 characters from the body field. While I'd like it to grab 20 chars in front of and behind the searched term so that the user can see what there term looks like in context:
SELECT id, title, substring(body, 0, 20) FROM content WHERE body LIKE '%mysql%' OR title LIKE '%mysql%';
Thanks
Here's the SQL you need:
SELECT
id,
title,
substring(body,
case
when locate('mysql', lower(body)) <= 20 then 1
else locate('mysql', lower(body)) - 20
end,
case
when locate('mysql', lower(body)) + 20 > length(body) then length(body)
else locate('mysql', lower(body)) + 20
end)
FROM content
WHERE lower(body) LIKE '%mysql%'
OR title LIKE '%mysql%'
limit 8;
FYI: Tested and works.
You could just pull the whole body value out and just extract the string in your code. If you're using php, you could do something like this, given you've already queried the body string and stored it in a var $body
$index = strpos($body, $searchStr);
$context = substr($body, $index-20, strlen($searchStr)+40);