HellowThar
HellowThar

Reputation: 83

Python Flask-Restful Error: Delete method in API is deleting ALL database entries

I've written a flask-restful API, and a SQLite database with peewee. I am able to 'get' on my list of art pieces that I am storing data for. I am also able to 'get' single pieces, 'post', and 'put' without issue. However, if I want to delete a single piece, my API is deleting ALL piece entries. Right now I'm just testing my API using postman so I know it isn't an AJAX or javascript error (which I will be writing later). Any guidance might be helpful.

I have tried to increase the number of queries required to make a delete request, where the created_by field in my db (which is an integer id) must match the id of the user authenticating. I created two users and posted two different pieces each, and running a delete request to a piece still deleted all of the pieces.

def piece_or_404(id):
    try:
        piece = models.Piece.get(models.Piece.id==id)
    except models.Piece.DoesNotExist:
        abort(404)
    else:
        return piece
class Piece(Resource):
    def __init__(self):
        self.reqparse = reqparse.RequestParser()
        self.reqparse.add_argument(
            'title',
            required=True,
            help='No title provided',
            location=['form', 'json']
        )
        self.reqparse.add_argument(
            'location',
            required=True,
            help='No url provided',
            location=['form', 'json']
        )
        self.reqparse.add_argument(
            'description',
            required=False,
            nullable=True,
            location=['form', 'json'],
        )
        self.reqparse.add_argument(
            'created',
            type=inputs.date,
            required=False,
            help='Date not in YYYY-mm-dd format',
            location=['form', 'json']
        )
        self.reqparse.add_argument(
            'price',
            type=inputs.positive,
            required=True,
            help='No price provided',
            location=['form', 'json']
        )
        self.reqparse.add_argument(
            'created_by',
            type=inputs.positive,
            required=True,
            help='No user provided',
            location=['form', 'json']
        )
        super().__init__()

    @auth.login_required
    def delete(self, id):
        try:
            Piece = models.Piece.select().where(
                models.Piece.id==id
            ).get()
        except models.Piece.DoesNotExist:
            return make_response(json.dumps(
                    {'error': 'That Piece does not exist or is not editable'}
                ), 403)
        query = Piece.delete()
        query.execute()
        return '', 204, {'Location': url_for('resources.pieces.pieces')}

If I have pieces with id's of 1, 2, and 3, then running a valid delete request on url.com/api/v1/pieces/1, should only delete the piece with id of 1.

Upvotes: 1

Views: 2769

Answers (1)

Andrew Yochum
Andrew Yochum

Reputation: 1056

The problem is you're using the table-level method delete() on an instance. There is also a row-level method delete_instance() you can use. See: http://docs.peewee-orm.com/en/latest/peewee/api.html#Model

You have two options on how to resolve this:

1 Change your call to delete to add a where that matches the select.

query = models.Piece.delete().where(models.Piece.id==id)
query.execute()

See http://docs.peewee-orm.com/en/latest/peewee/api.html#Model.delete (Note the warning!)

2 Use the delete_instance() method on the object instance:

Piece.delete_instance()

See http://docs.peewee-orm.com/en/latest/peewee/api.html#Model.delete_instance

Upvotes: 1

Related Questions