I have these two tables
User
| id | name |
| 1 | user1 |
| 2 | user2 |
| 3 | user3 |
Event
| id | name | created_by | published_by |
| 1 | event1 | 1 | 2 |
| 2 | event2 | 2 | 2 |
| 3 | event3 | 3 | 1 |
I want to join them that when Event table is displayed, all references are replaced by actual names from User table. This how my basic join query looks like
select
Event.id as event_id,
Event.name as event_name,
Event.created_by as event_created_by,
Event.published_by as event_published_by,
User.name as user_name
from
Event
left join User on created_by = User.id
which in SQLAlchemy translates to
db.session.query(Event, User).outerjoin(User, Event.created_by==User.id).all()
and produces following output
# event_id event_name event_created_by event_published_by user_name
1 1 event1 1 2 user1
2 2 event2 2 2 user2
3 3 event3 3 1 user3
where in fact it should look like:
# event_id event_name event_created_by event_published_by
1 1 event1 user1 user2
2 2 event2 user2 user2
3 3 event3 user3 user1
How can I achieve that in SQLAlchemy?
Use one additional LEFT join as below-
SELECT Event.id AS event_id,
Event.name AS event_name,
Event.created_by AS event_created_by,
Event.published_by AS event_published_by,
U1.name AS event_created_by,
U2.name AS event_published_by
FROM Event
LEFT JOIN User U1 ON Event.created_by = U1.id
LEFT JOIN User U2 ON Event.published_by = U2.id;
You can do the following SQLAlchemy query to get tuples of (event, created_by_user, published_by_user)
:
from sqlalchemy.orm import aliased
User1 = aliased(User)
User2 = aliased(User)
result = db.session.query(Event, User1, User2)\
.outerjoin(User1, Event.created_by == User1.id)\
.outerjoin(User2, Event.published_by == User2.id).all()
Which results in the following SQL:
SELECT event.id AS event_id,
event.name AS event_name,
event.created_by AS event_created_by,
event.published_by AS event_published_by,
user_1.id AS user_1_id,
user_1.name AS user_1_name,
user_2.id AS user_2_id,
user_2.name AS user_2_name
FROM event
LEFT OUTER JOIN user AS user_1 ON event.created_by = user_1.id
LEFT OUTER JOIN user AS user_2 ON event.published_by = user_2.id
And the following list of tuples:
[(<1, event1, 1, 2>, <1, user1>, <2, user2>), (<2, event2, 2, 2>, <2, user2>, <2, user2>), (<3, event3, 3, 1>, <3, user3>, <1, user1>)]
You can loop over these results getting the various values for example like this:
for event, created_by_user, published_by_user in result:
print(event)
print(created_by_user.name)
print(published_by_user.name)
我认为要获得event_published_by你应该在事件和用户之间进行另一次连接,但是在user.id = event.published_by
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.