[英]SQLAlchemy: create sqlalchemy query from sql query with subquery and inner join
I'm new to backend development and python. 我是后端开发和python的新手。 I'm working on creating a SQLAlchemy query from SQL query which has subquery and inner join. 我正在从具有子查询和内部联接的SQL查询创建SQLAlchemy查询。
I'm using python > 3.5, "oracle+cx_oracle" driver and SQLAlchemy==1.3.6 我正在使用python> 3.5,“ oracle + cx_oracle”驱动程序和SQLAlchemy == 1.3.6
The SQL query that I need to convert is: 我需要转换的SQL查询是:
SELECT DISTINCT d.*, t.max_date, t.USER_ID
FROM DATABASE_ONE d
INNER JOIN (
SELECT USER_ID, MAX(DATE_CREATED) max_date FROM (
SELECT * FROM DATABASE_ONE
WHERE USER_ID IN ('1','2','3')
AND CATEGORY = 'Users'
AND IS_DELETED IS NULL
)
GROUP BY USER_ID
) t on t.USER_ID = d.USER_ID AND t.max_date = d.DATE_CREATED
Below is the code that I've tried to convert the above SQL query to SQLAlchemy query. 下面是我尝试将上述SQL查询转换为SQLAlchemy查询的代码。
# --------------------- first query -------------------
first_query = (
Session.query(DatabaseOne)
.filter(
DatabaseOne.user_id.in_('1', '2', '3'),
DatabaseOne.category == "Obligor Rating Scorecards",
DatabaseOne.is_deleted == None,
)
.subquery("first_query")
)
# -------------------- second query --------------------
second_query = (
Session.query(
DatabaseOne.user_id,
func.max(DatabaseOne.date_created).label("max_date"),
)
.select_from(first_query)
.group_by(DatabaseOne.user_id)
.subquery("second_query")
)
# -------------------- final query --------------------
final_query = (
Session.query(
DatabaseOne, second_query.c.max_date, second_query.c.user_id
)
.join(
second_query,
and_(
second_query.c.user_id == DatabaseOne.user_id,
DatabaseOne.date_created == second_query.c.max_date,
),
)
.distinct(DatabaseOne)
.all()
)
Base on your SQL I think you are trying to query the lines which user_id is given and with max date. 根据您的SQL,我认为您正在尝试查询提供了user_id且具有最大日期的行。 So first maybe we can update the SQL a little: 所以首先也许我们可以稍微更新一下SQL:
SELECT DISTINCT d.*, t.max_date, t.USER_ID
FROM DATABASE_ONE d
INNER JOIN (
SELECT USER_ID, MAX(DATE_CREATED) max_date
FROM DATABASE_ONE
WHERE
USER_ID IN ('1','2','3')
AND CATEGORY = 'Users'
AND IS_DELETED IS NULL
GROUP BY USER_ID
) t on t.USER_ID = d.USER_ID AND t.max_date = d.DATE_CREATED
In these case it's easier to read and convert into SQLAlchemy language. 在这种情况下,更容易阅读并转换为SQLAlchemy语言。
Then the problem about your second SQLAlchemy query, is that you are trying to select from a subquery but the select is from origin table. 然后,关于第二个SQLAlchemy查询的问题是,您尝试从子查询中进行选择,但是选择是从原始表中进行选择。 If convert the second SQLAlchemy query into sql query, It's will look like: 如果将第二个SQLAlchemy查询转换为sql查询,则如下所示:
SELECT DATABASE_ONE.USER_ID, MAX(DATABASE_ONE.DATE_CREATED) max_date FROM (
SELECT * FROM DATABASE_ONE
WHERE USER_ID IN ('1','2','3')
AND CATEGORY = 'Users'
AND IS_DELETED IS NULL
)
GROUP BY DATABASE_ONE.USER_ID
The better way to write the SQLAlchemy query: 编写SQLAlchemy查询的更好方法:
subquery = Session.query(
DatabaseOne.user_id,
func.max(DatabaseOne.date_created).label("max_date"),
)
.filter(
DatabaseOne.user_id.in_('1', '2', '3'),
DatabaseOne.category == "Obligor Rating Scorecards",
DatabaseOne.is_deleted == None,
)
.group_by(DatabaseOne.user_id)
.subquery()
Session.query(
DatabaseOne, subquery.c.user_id, subquery.c.max_date # see the .c method to access column in subquery
).select_from(subquery).join(DatabaseOne).filter(DatabaseOne.user_id = subquery.c.user_id,DatabaseOne.date_created = subquery.c.max_date).all()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.