I wrote the following SQL query. How can I do the same thing in SQLAlchemy?
SELECT
T.campaign_id,
T.spend,
T.id
FROM activity_log T
WHERE T.end_time = (
SELECT MAX( T1.end_time ) FROM activity_log T1
WHERE T1.campaign_id = T.campaign_id and cast(T1.end_time as DATE) = cast(T.end_time as DATE)
);
Below should get you started:
T = aliased(ActivityLog, name="T")
T1 = aliased(ActivityLog, name="T1")
subquery = (
session.query(func.max(T1.end_time).label("end_time"))
.filter(T1.campaign_id == T.campaign_id)
.filter(cast(T1.end_time, Date) == cast(T.end_time, Date))
.correlate(T)
.as_scalar()
)
qry = (
session.query(T.campaign_id, T.spend, T.id)
.filter(T.end_time == subquery)
)
Related
Need help translating this SQL query into SQLAlchemy:
select
COALESCE(DATE_1,DATE_2) as DATE_COMPLETE,
QUESTIONS_CNT,
ANSWERS_CNT
from (
(select DATE as DATE_1,
count(distinct QUESTIONS) as QUESTIONS_CNT
from GUEST_USERS
where LOCATION like '%TEXAS%'
and DATE = '2021-08-08'
group by DATE
) temp1
full join
(select DATE as DATE_2,
count(distinct ANSWERS) as ANSWERS_CNT
from USERS
where LOCATION like '%TEXAS%'
and DATE = '2021-08-08'
group by DATE
) temp2
on temp1.DATE_1=temp2.DATE_2
)
Mainly struggling with the join of the two subqueries. I've tried this (just for the join part of the SQL):
query1 = db.session.query(
GUEST_USERS.DATE_WEEK_START.label("DATE_1"),
func.count(GUEST_USERS.QUESTIONS).label("QUESTIONS_CNT")
).filter(
GUEST_USERS.LOCATION.like("%TEXAS%"),
GUEST_USERS.DATE == "2021-08-08"
).group_by(GUEST_USERS.DATE)
query2 = db_session_stg.query(
USERS.DATE.label("DATE_2"),
func.count(USERS.ANSWERS).label("ANSWERS_CNT")
).filter(
USERS.LOCATION.like("%TEXAS%"),
USERS.DATE == "2021-08-08"
).group_by(USERS.DATE)
sq2 = query2.subquery()
query1_results = query1.join(
sq2,
sq2.c.DATE_2 == GUEST_USERS.DATE)
).all()
In this output I receive only the DATE_1 column and the QUESTIONS_CNT columns. Any idea why the selected output from the subquery is not being returned in the result?
Not sure if this is the best solution but this is how I got it to work. Using 3 subqueries essentially.
query1 = db.session.query(
GUEST_USERS.DATE_WEEK_START.label("DATE_1"),
func.count(GUEST_USERS.QUESTIONS).label("QUESTIONS_CNT")
).filter(
GUEST_USERS.LOCATION.like("%TEXAS%"),
GUEST_USERS.DATE == "2021-08-08"
).group_by(GUEST_USERS.DATE)
query2 = db_session_stg.query(
USERS.DATE.label("DATE_2"),
func.count(USERS.ANSWERS).label("ANSWERS_CNT")
).filter(
USERS.LOCATION.like("%TEXAS%"),
USERS.DATE == "2021-08-08"
).group_by(USERS.DATE)
sq1 = query1.subquery()
sq2 = query2.subquery()
query3 = db.session.query(sq1, sq2).join(
sq2,
sq2.c.DATE_2 == sq1.c.DATE_1)
sq3 = query3.subquery()
query4 = db.session.query(
func.coalesce(
sq3.c.DATE_1, sq3.c.DATE_2),
sq3.c.QUESTIONS_CNT,
sq3.c.ANSWERS_CNT
)
results = query4.all()
The above function has parameters endTime, startTime, list1 and column_filter to it and I am trying to read a query by making the WHERE clause conditions parameterized.
endT = endTime
startT = startTime
myList = ",".join("'" + str(i) + "'" for i in list1)
queryArgs = {'db': devDB,
'schema': dbo,
'table': table_xyz,
'columns': ','.join(column_filter)}
query = '''
WITH TIME_SERIES AS
(SELECT ROW_NUMBER() OVER (PARTITION BY LocId ORDER BY Created_Time DESC) RANK, {columns}
from {schema}.{table}
WHERE s_no in ? AND
StartTime >= ? AND
EndTime <= ? )
SELECT {columns} FROM TIME_SERIES WHERE RANK = 1
'''.format(**queryArgs)
args = (myList, startT, endT)
return self.read(query, args)
The below is my read which connects to the DB to fetch records and a condition is also added to check if its parameterized or not.
def read(self, query, parameterValues = None):
cursor = self.connect(cursor=True)
if parameterValues is not None:
rows = cursor.execute(query, parameterValues)
else:
rows = cursor.execute(query)
df = pd.DataFrame.from_records(rows.fetchall())
if len(df.columns) > 0:
df.columns = [x[0] for x in cursor.description]
cursor.close()
return df
The query args are getting picked up but not the parameterized values. In my case, it is going inside the read method with parameter values of (myList, startT ,endT) as a tuple. The query in WHERE clause remains unchanged (parameters not able to replace ? ), and as a result I am not able to fetch any records. Can you specify where I might be going wrong?
I'm new in sqlalchemy, please help. I have this SQL query:
SELECT * FROM films
WHERE (
SELECT count(film_to_genre.id) FROM film_to_genre
WHERE films.id = film_to_genre.film_id AND film_to_genre.genre_id IN (2, 14)
) = 2
And I want to write it in SqlAlchemy. This is what I've tried:
db.query(models.Film)
.filter(db.query(func.count(models.FilmToGenre.id))
.filter(and_(models.Film.id == models.FilmToGenre.film_id,
models.FilmToGenre.genre_id.in_(genre_ids)))
.subquery().count == len(genre_ids)))
It converts to this SQL (problem in clause "WHERE false", it evaluates subquery immediately):
SELECT films.id AS films_id, films.kinopoisk_id AS films_kinopoisk_id, films.title AS films_title, films.year AS films_year, films.budget AS films_budget, films.run_time AS films_run_time, films.description AS films_description
FROM films JOIN film_to_genre ON films.id = film_to_genre.film_id
WHERE false
LIMIT %(param_1)s OFFSET %(param_2)s
Add .c to access the column of the subquery:
Instead of subquery().count == len(genre_ids)) please use subquery().c.count == len(genre_ids))
I do, however, prefer as_scalar option:
genre_ids = [2, 14]
sq = (
session.query(
func.count(FilmToGenre.id)
)
.filter(
and_(
FilmToGenre.film_id == Film.id,
FilmToGenre.genre_id.in_(genre_ids),
)
)
.as_scalar()
)
q = (
session.query(Film)
.filter(sq == len(genre_ids))
)
I want to add branch_id variable in sql query. How can I use?When I use below code,I got psycopg2.ProgrammingError: column reference "branch_id" is ambiguous.
branch_id = self.env.user.branch_id.id
query = '''
SELECT DISTINCT l.partner_id, res_partner.name AS name, UPPER(res_partner.name) AS UPNAME, CASE WHEN prop.value_text IS NULL THEN 'normal' ELSE prop.value_text END AS trust
FROM account_move_line AS l
LEFT JOIN res_partner ON l.partner_id = res_partner.id
LEFT JOIN ir_property prop ON (prop.res_id = 'res.partner,'||res_partner.id AND prop.name='trust' AND prop.company_id=%s),
account_account, account_move am
WHERE (l.account_id = account_account.id)
AND (l.move_id = am.id)
AND (am.state IN %s)
AND (account_account.internal_type IN %s)
AND (
l.reconciled IS NOT TRUE
OR l.id IN(
SELECT credit_move_id FROM account_partial_reconcile where max_date > %s
UNION ALL
SELECT debit_move_id FROM account_partial_reconcile where max_date > %s
)
)
''' + partner_clause + '''
AND (l.date <= %s)
AND (l.branch_id = branch_id)
AND l.company_id IN %s
ORDER BY UPPER(res_partner.name)'''
arg_list = (self.env.company.id,) + arg_list
cr.execute(query, arg_list)
I would prefer variable substitute using name for your query, which will make this more understandable. For example:
branch_id = self.env.user.branch_id.id
query = '''
SELECT DISTINCT l.partner_id, res_partner.name AS name, UPPER(res_partner.name) AS UPNAME, CASE WHEN prop.value_text IS NULL THEN 'normal' ELSE prop.value_text END AS trust
FROM account_move_line AS l
LEFT JOIN res_partner ON l.partner_id = res_partner.id
LEFT JOIN ir_property prop ON (prop.res_id = 'res.partner,'||res_partner.id AND prop.name='trust' AND prop.company_id=%(company_id)s),
account_account, account_move am
WHERE (l.account_id = account_account.id)
AND (l.move_id = am.id)
AND (am.state IN %(state)s)
AND (account_account.internal_type IN %(internal_types)s
AND (
l.reconciled IS NOT TRUE
OR l.id IN(
SELECT credit_move_id FROM account_partial_reconcile where max_date > %(max_date)s
UNION ALL
SELECT debit_move_id FROM account_partial_reconcile where max_date > %(max_date)s
)
)
''' + partner_clause + '''
AND (l.date <= %(date)s)
AND (l.branch_id = %(branch_id)s)
AND l.company_id IN %(company_id)s
ORDER BY UPPER(res_partner.name)'''
args = {
'company_id': ...,
'internal_types': ...,
'max_date': ...,
'date': ...,
'branch_id': ...,
}
cr.execute(query, args)
I need to compare the user input date kakko (yyyy-mm-dd format) with the CreateDate and UpdateDate in table productinfo and return the result.
This does not work.
cur.execute("SELECT * FROM `productinfo` WHERE CreateDate > %s-%s-%s AND CreateDate <= (SELECT MAX( UpdateDate ) FROM productinfo) AND Updatedate = (SELECT MAX( UpdateDate ) FROM productinfo) ",kakko)
db.commit()
Try below code
sql ='SELECT
*
FROM
productinfo
WHERE
CreateDate > ? AND CreateDate <= (SELECT
MAX(UpdateDate)
FROM
productinfo) AND Updatedate = (SELECT
MAX(UpdateDate)
FROM
productinfo)';
cur.execute(sql,kakko)
db.commit
cur.execute("SELECT * FROM `productinfo` WHERE CreateDate > '%s'" %(kakko,))
result = cur.fetchall()
works!