#πŸ”’ SQLAlchemy: filter 3 tables

5 messages Β· Page 1 of 1 (latest)

feral yacht
#

Hi everyone,
This is the following of my question from yesterday, which I still have trouble with.

Shortly: i have the db represented in the attached picture. The db contains a fixed ammount of recordings, and each user must rate each recording (each individual rating is stored in the ratings table).

I'm trying to write a SQLAlchemy query that returns all users who still haven't rated all recordings.

e.g.: I have:
4 recordings, with IDs 1, 2, 3, 4
4 users with IDs 1,2,3,4
and the following ratings:
{user_id: 1, recording_id: 1} {user_id: 1, recording_id: 2} {user_id: 1, recording_id: 3} {user_id: 1, recording_id: 4}
{user_id: 2, recording_id: 1} {user_id: 2, recording_id: 3} {user_id: 2, recording_id: 4}
{user_id: 4, recording_id: 1} {user_id: 4, recording_id: 2} {user_id: 4, recording_id: 3} {user_id: 4, recording_id: 4}

I want my query to return the users with IDs 2 and 3, as user 2 hasn't rated the recording 2 and the user 3 hasn't rated a single recording.

I thought I could achieve this by:
for each **user **in the **users **table, looking at each **recording **from the **recordings **table, and return the **user **if the **ratings **table didn't contain a **rating **with Rating.user_id == User.id and Rating.recording_id == Recording.id

I'm pretty new to SQL in general, so I struggled to reach the following query that unfortunately always return an empty list...

results = session.query(User).filter(
        select(Recording).exists().where(
            ~select(Rating).exists().where(
                Rating.recording_id == Recording.id and Rating.user_id == User.id
                )
            )
        ).all()

I think I need some help from people who actually know what they're doing with SQL queries!! πŸ˜‰

upbeat fractalBOT
#

@feral yacht

Python help channel opened

Remember to:

  • Ask your Python question, not if you can ask or if there's an expert who can help.
  • Show a code sample as text (rather than a screenshot) and the error message, if you've got one.
  • Explain what you expect to happen and what actually happens.

:warning: Do not pip install anything that isn't related to your question, especially if asked to over DMs.

feral yacht
#

I changed my approach and wrote the following:

results = session.query(User).filter(
        ~Recording.id.in_(
            select(Rating.recording_id).where(Rating.user_id == User.id)
        )
        ).all()

It seems to work as intended, but I have a warning in the console:

SAWarning: SELECT statement has a cartesian product between FROM element(s) "recordings" and FROM element "users". Apply join condition(s) between each element to resolve.
).all()
5

I tried to join the tables at the beginning of the query session.query(User).join(Rating).join(Recording).filter but then the program just doesn't run because of a Select statement returned no FROM clauses due to auto-correlation; specify correlate(<tables>) to control correlation manually error.

I feel like I'm trying to guess stuff here and I can't find a simple way to resolve the warning

upbeat fractalBOT
#

@feral yacht

Python help channel closed

This help channel has been closed and it's no longer possible to send messages here. If your question wasn't answered, feel free to create a new post in #1035199133436354600. To maximize your chances of getting a response, check out this guide on asking good questions.