Skip to content

Strengthen add_assignment API if unique constrain fails #1161

@Yenthe666

Description

@Yenthe666

Operating system

Ubuntu 18.04.1

nbgrader --version

0.5.5

jupyterhub --version (if used with JupyterHub)

No hub.

jupyter notebook --version

5.7.8

Expected behavior

When creating an assignment through the API there should be a check to make sure an assignment with the same name does not yet exist and if it does it should gracefully fail with a NotFound equivalent.

Actual behavior

There is no check that makes sure that an assignment with the same name exists yet. This will trigger an sqlalchemy.exc.IntegrityError if there is already an assignment as the name is not unique and there is a constraint on assignment.name.

Steps to reproduce the behavior

Run the following code to create a new assignment:

import pandas as pd
from nbgrader.api import Gradebook, MissingEntry

# Create a database connection
with Gradebook('sqlite:///gradebook.db') as gb:

    # Create an assignment
    gb.add_assignment('course101')

    # List assignments
    assignments = gb.assignments
    print('assignments: ' + str(assignments))

It'll work fine and your course is created. Now, run this code a second time again. You will now get a traceback from sqlalchemy:

sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) UNIQUE constraint failed: assignment.name
[SQL: INSERT INTO assignment (id, name, duedate) VALUES (?, ?, ?)]
[parameters: ('731761fc4fa2476eae8de1160cc30c41', 'course101', None)]
(Background on this error at: http://sqlalche.me/e/gkpj)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "jupyter_course_generatorv2.py", line 9, in <module>
    gb.add_assignment('course101')
  File "/usr/local/lib/python3.6/dist-packages/nbgrader/api.py", line 1215, in add_assignment
    raise InvalidEntry(*e.args)
nbgrader.api.InvalidEntry: (sqlite3.IntegrityError) UNIQUE constraint failed: assignment.name

The problem is that if this happens your whole script will fail as the traceback stops the Python process from running. This can cause big problems if you've automated creating instances through API calls as you wouldn't directly notice most likely.

Edit: I do know we could do the check in our code too (for example try/catch) but I think it should be handled at the framework level, not at the implementation level. I hope you agree.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions