Skip to content

Sql autorunner#398

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

Sql autorunner#398
khsergvl wants to merge 10 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.

print(f"An unexpected error occurred: {e}")
json.dump(test_result, json_file, indent=2)
json_file.close()
assert True, "test execution query {} result {}".format(queries, test_result)
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 am not sure if this Assert True statement is of any use. I think it can be removed.

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 purpose of it to have report in the future in case DSI will want to go with unit testing style.

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.

In that case, we should probably comment the line and add a comment about the intent. What do you think?

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

run_assignment(sqlite_db, file_path)

def run_assignment(sqlite_db, file_path):
json_file = open("test-results.json", "w")
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.

Just a suggestion to use with open("..."). It will ensure that the file is always properly closed, even if an exception occurs before close()

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.

Well yeah, it normally it make sense to close streams.

run: |
pytest tests/test_assignment.py --file_path="${{steps.changes.outputs.assignment_changed}}" --tb=short --disable-warnings \
--junitxml=pytest-report.xml || true

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 am not sure if this option --junitxml=pytest-report.xml is needed? pytest-report.xml doesn't seem to be created.

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 purpose of it to have report in the future in case DSI will want to go with unit testing style.


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.

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