Получение IntegrityError при попытке обновить записи в моей базе данных PostgreSQL с помощью peewee. Однако это происходит только тогда, когда я пробую метод HTTP PUT.
Использование Flask и Flask-Restful для создания ресурсов API. ПОЛУЧИТЬ, УДАЛИТЬ в один пост в блоге работает отлично. Сообщение в корзину работает отлично
Я могу запустить точно такой же код через REPL, и он отлично работает. Что еще более странно, так это то, что API внезапно сломался, я вчера тестировал эту функцию, и все было в порядке. Теперь не могу определить, что изменилось.
Вот моя модель крошки в models.py
class BlogPost(Model):
title = CharField(default='', unique=True)
content = TextField(default='')
created = DateTimeField(default=datetime.datetime.now)
class Meta:
database = DATABASE
Вот ресурс для одного сообщения блога в resources.blogposts.py.
class BlogPost(Resource):
def __init__(self):
self.reqparse = reqparse.RequestParser()
self.reqparse.add_argument(
'title',
required=False,
help='No title provided',
location=['form', 'json']
)
self.reqparse.add_argument(
'content',
required=False,
nullable=True,
location=['form', 'json'],
default=''
)
super().__init__()
@marshal_with(blogpost_fields)
def get(self, id):
return (blogpost_or_404(id))
@marshal_with(blogpost_fields)
@auth.login_required
def put(self, id):
args = self.reqparse.parse_args()
try:
blogpost = models.BlogPost.get(models.BlogPost.id==id)
except models.BlogPost.DoesNotExist:
return make_response(json.dumps(
{'error': 'That blogpost does not exist or is not editable'}
), 403)
else:
query = blogpost.update(**args)
query.execute()
blogpost = (blogpost_or_404(id))
return (blogpost, 200, {
'Location': url_for('resources.blogposts.blogpost', id=id)
})
@auth.login_required
def delete(self, id):
try:
blogpost = models.BlogPost.select().where(
models.BlogPost.id==id
).get()
except models.BlogPost.DoesNotExist:
return make_response(json.dumps(
{'error': 'That blogpost does not exist or is not editable'}
), 403)
else:
query = blogpost.delete().where(models.BlogPost.id==id)
query.execute()
return '', 204, {'Location': url_for('resources.blogposts.blogposts')}
blogposts_api = Blueprint('resources.blogposts', __name__)
api = Api(blogposts_api)
api.add_resource(
BlogPost,
'api/v1/blogposts/<int:id>',
endpoint='blogpost'
)
Если я выполню GET для http://localhost:8000/api/v1/blogposts/8 Я получаю в таблице свой единственный пост в блоге (для проверки я удалил все, кроме этого)
{
"id": 8,
"title": "Test3",
"content": "This is to test changes to BlogPost 1",
"created": "Wed, 19 Jun 2019 12:44:31 -0000"
}
Однако, если я PUT на тот же URL-адрес, я получаю уникальное ограничение. У меня определенно нет записи в базе данных с таким заголовком.
{
"title": "9sdnfsudngfisdngondasgjns",
"content": "lkbksigsndignsoidugnlis",
}
Я могу сделать это в REPL, и он отлично работает, это должно быть то же самое, что и то, что я делаю выше:
blogpost = models.BlogPost.get(models.BlogPost.id==8)
blogpost.update(
title="9sdnfsudngfisdngondasgjns",
content="lkbksigsndignsoidugnlis"
)
blogpost.execute()
Фактическая ошибка:
peewee.IntegrityError: повторяющееся значение ключа нарушает уникальное ограничение «blogpost_title» ПОДРОБНОСТЬ: Ключ (название) = (9sdnfsudngfisdngondasgjns) уже существует.
РЕДАКТИРОВАТЬ: перед ошибкой peewee psycopg2 также выдает эту ошибку:
UniqueViolation: повторяющееся значение ключа нарушает уникальное ограничение «user_username_key» ПОДРОБНОСТЬ: Ключ (имя пользователя) = (9sdnfsudngfisdngondasgjns) уже существует.