How to get length of query result SqlAlchemy - python

I have simple query using SqlAlchemy ORM:
query = DBsession.query(AssetsItem).filter_by(
AssetsItem.id > 10,
AssetsItem.country = 'England'
)
How can i get length of my query result. I want to know how much AssetsItem i would get by this query

query = DBsession.query(AssetsItem).filter_by(
AssetsItem.id > 10,
AssetsItem.country = 'England'
)
your_count = query.count()
Documentation

Related

How to resolve SQLAlchemy Union Throwing Error

I'm using SQL Alchemy(Python, SQLServer) Union on two queries. It throws me the below error. Please help me in resolving it.
query1 = db.query(Employee.LastName).filter(Employee.Age == 30).all()
query2 = db.query(Employee.LastName).filter(Employee.Salary > 25000).all()
query3 = union(query1, query2).all()
**"SELECT construct for inclusion in UNION or other set construct expected, got [('Joseph',),('Alan',),('Joseph',)]."**
Also tried the below query and it throws the below error
query1 = db.query(Employee.LastName).filter(Employee.Age == 30).all()
query2 = db.query(Employee.LastName).filter(Employee.Salary > 25000).all()
query3 = query1.union(query2).all()
**"'list' object has no attribute 'union'"**
Remove the .all() from the first two queries, it turns the queries into lists, but you want to pass Query instances to union.
query1 = db.query(Employee.LastName).filter(Employee.Age == 30) # <- Query
query2 = db.query(Employee.LastName).filter(Employee.Salary > 25000) # <- Query
result = query1.union(query2).all() # <- List

Django Subquery, ORA-00904: invalid identifier

The query below works as raw sql
SELECT WORK_ORDER.*,(SELECT COMPLETE FROM SAMPLE WHERE COMPLETE = 'TRUE' AND
ARF_ID = WORK_ORDER.ARF_ID AND ROWNUM <= 1) AS SAMPLE_COMPLETE, (DUE_DATE -
SYSDATE) AS DUE_IN FROM WORK_ORDER WHERE COMPLETE = 'FALSE' ORDER BY
DUE_DATE ASC
The following Django Queryset does not work
subquery = Sample.objects.filter(complete = 'TRUE', arf_id = models.OuterRef('arf_id'))[:1]
workOrderList = WorkOrder.objects.annotate(sample_complete= models.Subquery(subquery.values('complete'))).annotate(due_in= models.F('due_date') - datetime.now()).filter(complete = 'FALSE').order_by('due_date')
which produces this query when running workOrderList.query
SELECT "WORK_ORDER"."ARF_ID", "WORK_ORDER"."COMPANY_NAME",
"WORK_ORDER"."COMPANY_ADDRESS", "WORK_ORDER"."CONTACT_TELEPHONE",
"WORK_ORDER"."ORDER_DATE", "WORK_ORDER"."DUE_DATE",
"WORK_ORDER"."ARF_NUMBER", "WORK_ORDER"."COMPLETE",
"WORK_ORDER"."COMPLETE_DATE", "WORK_ORDER"."REPORTED",
"WORK_ORDER"."REPORTED_DATE", "WORK_ORDER"."COMPANY_CODE", (SELECT * FROM
(SELECT "_SUB".* FROM (SELECT U0."COMPLETE" AS Col1 FROM "SAMPLE" U0 WHERE
(U0."COMPLETE" = TRUE AND U0."ARF_ID" = ("WORK_ORDER"."ARF_ID"))) "_SUB"
WHERE ROWNUM <= 1)) AS "SAMPLE_COMPLETE", ("WORK_ORDER"."DUE_DATE" - 2019-
01-28 13:00:51.043013) AS "DUE_IN" FROM "WORK_ORDER" WHERE
"WORK_ORDER"."COMPLETE" = FALSE ORDER BY "WORK_ORDER"."DUE_DATE" ASC
This returns error
cx_Oracle.DatabaseError: ORA-00904: "WORK_ORDER"."ARF_ID": invalid identifier
I am using Django 1.11.13 and this is a legacy database, I am comfortable using raw sql to query data but would like to learn/utilize the Django ORM the correct way so any fix or explanation why this won't work is helpful to me.
Using the Exists() subclass in this case works is a solution to accomplish the the overall goal:
workOrderList = WorkOrder.objects.annotate(sample_complete= models.Exists(subquery.values('complete')))
.annotate(due_in= models.F('due_date') - datetime.now()).filter(complete = 'FALSE').order_by('due_date')
I am still looking for a solution that uses the Subquery() method

Performing union with three queries - SQLAlchemy

In my project setup querying is being done based on the SQLAlchemy.
As per my previous requirements I have done the union with two queries.
Now I need to do Union with three queries.
Code is as follows:
query1 = query1.filter(model.name == "in-addr.arpa.")
query2 = query2.filter(model.tenant_id.in_(tenant_ids))
query = query1.union(query2)
Now Here I need to add one more query as follows:
query3 = query3.filter(model.tenant_id == context.tenant_id)
So I need to perform Union with all the three queries.
The solution is following:
query1 = query1.filter(model.name == "in-addr.arpa.")
query2 = query2.filter(model.tenant_id.in_(tenant_ids))
query3 = query3.filter(model.tenant_id == context.tenant_id)
query = query1.union(query2,query3)
This is how I did this in SQLAlchemy 1.3
from sqlalchemy import union
query1 = query1.filter(model.name == "in-addr.arpa.")
query2 = query2.filter(model.tenant_id.in_(tenant_ids))
query3 = query3.filter(model.tenant_id == context.tenant_id)
all_queries = [query1, query2, query3]
golden_set = union(*all_queries)
The change here is that the union method accepts a list of SQLAlchemy selectables.
In SQLAlchemy 1.4 you will need to use the function union and pass the queries as positional arguments instead of a list.
from sqlalchemy import union
query1 = query1.filter(model.name == "in-addr.arpa.")
query2 = query2.filter(model.tenant_id.in_(tenant_ids))
query3 = query3.filter(model.tenant_id == context.tenant_id)
query = union(query1, query2, query3)

SQLAlchemy Joining with subquery issue

I am trying to translate SQL into SQLAlchemy. The SQL version of the query I want is as follows:
SELECT * from calendarEventAttendee
JOIN calendarEventAttendanceActual ON calendarEventAttendanceActual.id = calendarEventAttendee.attendanceActualId
LEFT JOIN
(SELECT bill.id, bill.personId, billToEvent.eventId FROM bill JOIN billToEvent ON bill.id = billToEvent.billId) b
ON b.eventId = calendarEventAttendee.eventId AND b.personId = calendarEventAttendee.personId
WHERE b.id is NULL
My SQLAlchemy query is as follows:
query = db.session.query(CalendarEventAttendee).join(CalendarEventAttendanceActual)
sub_query = db.session.query(Bill, BillToEvent).join(BillToEvent, BillToEvent.billId == Bill.id).subquery()
query = query.outerjoin(sub_query, and_(sub_query.Bill.personId == CalendarEventAttendee.personId, Bill.eventId == CalendarEventAttendee.eventId))
results = query.all()
I am getting an error AttributeError: 'Alias' object has no attribute 'Bill'
If I adjust the SQLAlchemy query to the following:
sub_query = db.session.query(Bill, BillToEvent).join(BillToEvent, BillToEvent.billId == Bill.id).subquery()
query = query.outerjoin(sub_query, and_(sub_query.Bill.personId == CalendarEventAttendee.personId, sub_query.BillToEvent.eventId == CalendarEventAttendee.eventId))
results = query.all()
I get an error AttributeError: Bill
Any help would be appreciated, thanks!
Once you call subquery(), there is no access to objects, but only to columns via .c.{column_name} accessor.
Do the following for sub_query instead: load only the columns you need in order to avoid any name collisions:
sub_query = db.session.query(
Bill.id, Bill.personId, BillToEvent.eventId
).join(BillToEvent, BillToEvent.billId == Bill.id).subquery()
Then in your query use column names with .c.column_name:
query = query.outerjoin(
sub_query, and_(
sub_query.c.personId == CalendarEventAttendee.personId,
sub_query.c.eventId == CalendarEventAttendee.eventId)
)
results = query.all()

How can I get int result from web python sql query?

My code is as follows. My question is, how can I get the int result from the query?
import web
db = web.database(...)
rs = db.query('select max(id) from tablename')
The query method returns a list. Then you can access your calculated column by using an alias. If you don't want to use an alias, then I think you can do rs[0]['max(id)']
rs = db.query('select max(id) as max_value from tablename')
print rs[0].max_value
This is based on the example used in the web.py docs: http://webpy.org/cookbook/query
Here is the example from the link:
import web
db = web.database(dbn='postgres', db='mydata', user='dbuser', pw='')
results = db.query("SELECT COUNT(*) AS total_users FROM users")
print results[0].total_users # -> prints number of entries in 'users' table

Categories