Skip to content

Sql autorunner#398

Open
khsergvl wants to merge 11 commits intoUofT-DSI:mainfrom
khsergvl:sql-autorunner
Open

Sql autorunner#398
khsergvl wants to merge 11 commits intoUofT-DSI:mainfrom
khsergvl:sql-autorunner

Conversation

@khsergvl
Copy link
Copy Markdown
Collaborator

@khsergvl khsergvl commented Mar 24, 2026

What changes are you trying to make? (e.g. Adding or removing code, refactoring existing code, adding reports)

This pull request adds github workflow to run students queries and help to review assignments.
Result is truncated to up to 3 rows (github supports up to 65k symbols per comment). In case of failures it should not make any problem to students.

Was there another approach you were thinking about making? If so, what approach(es) were you thinking of?

It is built on the top of python unit test runner, and might be useful in case DSI will decide to implement strict unit test / test development driven assignment marking. I think we can change a trigger instead of on PR to on workflow_dispatch and trigger it manually during assignment review.

Were there any challenges? If so, what issue(s) did you face? How did you overcome it?

There are few limitations here, since runner right now executes only one sql statement within markers(query - end query).
We can collaborate to improve it, if it will be necessary.

How were these changes tested?

Please look here to see testing results:
https://github.com/khsergvl/sql/pulls
Two latest worse attention.

Other cohorts:

assignment sql files need markers to keep file parsed.

Checklist

  • I can confirm that my changes are working as intended, *** any modification proposals are welcome ***
    With love to open-source

@mrpotatocode
Copy link
Copy Markdown
Member

I have reviewed this conceptually but not at the code level.
It seems like a very sensible build and Sergii has formatted runner output in an easy-to-read form. I would like to see this merged, but since I have not used pytest, I'd greatly appreciate @danielrazavi and @RohanAlexander to give feedback!

@khsergvl
Copy link
Copy Markdown
Collaborator Author

@mrpotatocode
What you can do, you can fork repository to your personal account, merge the branch to your fork's main and try to submit a pr in the same way how students will do.
This is how it can be easy tested.
I can recommend to do it to every contributor / reviewer assigned.

Copy link
Copy Markdown
Collaborator

@anjali-deshpande-hub anjali-deshpande-hub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall the code looks really good! There are a few of easy fixes. I have added inline comments.
I think these two are most important:

  • Save errors to JSON (not just print) (line 78)
  • Empty query (line 39)

Depending upon what we decide about error handling, we can fix review comment on line 20. We can choose to gracefully handle the error and always generate JSON file, for instance.

The rest of review comments are easy fixes.

rows = run_query(sqlite_db, parsed_query['query'])
test_result.append( { "number": parsed_query['number'], "query": parsed_query['query'], "result": rows[0:3] })
except Exception as e:
print(f"An unexpected error occurred: {e}")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of this print, how about we store the error in the test-results.json file like how we store the result in the json file. We can do something like -
test_result.append({"number": parsed_query['number'], "query": parsed_query['query'], "error": str(e)})

and then parse "error" tag in the JSON file to output "Error". The reason I am saying this is because the print swallows the error and doesn't output anywhere.

See test case anjali-deshpande-hub#1, I have Query 4 which has "FROM" clause missing (incorrect syntax) and the autorunner chooses to skip Query 4. Only Query 3,5 are shown.

I think its better to show the Query and may be under "Results", show "Error"

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm was not sure what is the best approach here, since it doesn't gives an explanation not to LS not too students what to do? In the same time I'm aware about possible case when multiple sql queries will go as one task and fetchall() might fail, but queries still valid. I.e. insert https://github.com/UofT-DSI/sql/blob/main/03_instructional_team/DC_Cohort_Rubrics/LS_Assignment2_rubric.md

if stripped.lower().startswith("--query"):
if current_query is not None:
raise AssertionError("Nested QUERY blocks are not allowed")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Assertions in this function will result in the autorunner to fail. I understand that in these cases, the learning support can see the error messages under 'Run tests' section of the workflow? See test case anjali-deshpande-hub#2
Depending upon what we decide to about error handling, this can change.

continue # ignore stray END

query = "\n".join(buffer).strip().rstrip(";")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think somewhere here we should code for missing query. The query markers are present, but the code inside is missing. See anjali-deshpande-hub#1, Currently I am seeing:

✅ Query 1:
**,

Results:
No data

Instead, maybe we can say:

✅ Query 1:
No query


def pytest_addoption(parser):
parser.addoption("--file_path", action="store", default="02_activities/assignments/DC_Cohort/assignment1.sql")

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can choose to save these filepaths in environment variable (default="02_activities/assignments/DC_Cohort/assignment1.sql", "05_src/sql/farmersmarket.db"). Maybe under "env" key in .yml file

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The intent to provide a file name as parameter here, coming from the point, that we have multiple cohort running in parallel. It can be used for Micro credentials, etc. So default is basically default. In the same time this path is extracted from the file list modified in the pull request.

Copy link
Copy Markdown
Collaborator

@anjali-deshpande-hub anjali-deshpande-hub left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@khsergvl Can you please look at

  1. #anjali-deshpande-hub#1 In this PR, the assignment SQL file had some queries that are missing and Query 4 which has error; but the error shown by autorunner is incorrect.
  2. #anjali-deshpande-hub#2 Here the assignment SQL file has correct answers, but the runner is failing. The file is running on DbBrowser. Maybe I am missing something. Please check.
Screenshot 2026-03-29 190606

body += `${table} \n`
body += `\n`
body += `-------------------------------------------------------- \n`
if (result.result.trim().length > 0) {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we have a problem with new if statement. I am not sure why this was added. Empty result sets are skipped entirely. There is no way to distinguish empty result set queries from non‑executed or failed ones.

@Dmytro-Bonislavskyi
Copy link
Copy Markdown
Collaborator

Dmytro-Bonislavskyi commented Mar 30, 2026

Hi @khsergvl after merging last changes we have an issue with: if (result.result.trim().length > 0) {
which we can change to if (result.result && result.result.length > 0) { to make it work for now.

Regarding " distinguish empty result set queries from non‑executed or failed ones." we can return something like this for both:
Queries 10 and 12:
image

End for errors (Q 2):
image

You can check my last PR in my repo to use this changes (If you want I can propose this changes to your repo and you can add them to next commit for current PR):
Dmytro-Bonislavskyi/sql_DC3#2

@khsergvl
Copy link
Copy Markdown
Collaborator Author

@Dmytro-Bonislavskyi well yeah, the condition of undefined was resolved. A spread of node js ...
About error handling I have something that was reported as a limitation. As far as I can remember fetch all doesn't work properly for multiple queries in the sql session. It means if the student will post i.e.:
Insert into ...; and After will do select * from fetchall will fail. In the same time queries would be valid.
This is the reason I decided to omit error handling and posting errors results ( they need to be trimmed also because of PR comment length limitation).

@khsergvl
Copy link
Copy Markdown
Collaborator Author

@anjali-deshpande-hub

@Dmytro-Bonislavskyi
Copy link
Copy Markdown
Collaborator

@khsergvl Sergii, Yes, I can see it with technically correct query with 2 statement like this (evaluating as error)
image
We can try to treat it as multi query in version 2 :).

And, we still can use "no rows returned" kind for "Empty-correct"/"just Empty" results to not just skip them silently.

@Dmytro-Bonislavskyi
Copy link
Copy Markdown
Collaborator

@khsergvl I add handling for multiple statements Queries in my repo, so now we can have it and also keep error handling as 3rd type. Give me other "limit cases", I can check them too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants