仅通过API获取唯一约束的peewee IntegrityError

2024-09-27 21:26:46 发布

您现在位置:Python中文网/ 问答频道 /正文

在尝试用peeweee更新PostgreSQL数据库上的记录时获取IntegrityError。但是,只有在尝试httpput方法时才会发生这种情况。你知道吗

使用Flask和Flask Restful创建API资源。获取、删除到一篇博客文章效果很好。投递到桶里的方法很好

我可以在REPL中运行完全相同的代码,而且效果很好。更奇怪的是API突然坏了,我昨天测试了这个函数,结果很好。现在我不知道是什么改变了。你知道吗

这是我的皮威模型型号.py你知道吗


class BlogPost(Model):
    title = CharField(default='', unique=True)
    content = TextField(default='')
    created = DateTimeField(default=datetime.datetime.now)

    class Meta:
        database = DATABASE

以下是中单个BlogPost的资源资源.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 to http://localhost:8000/api/v1/blogposts/8,我会得到表中唯一的BlogPost(我删除了所有要测试的BlogPost)


{
    "id": 8,
    "title": "Test3",
    "content": "This is to test changes to BlogPost 1",
    "created": "Wed, 19 Jun 2019 12:44:31 -0000"
}

但是,如果我放在同一个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\u title”详细信息:键(title)=(9sdnfsudngfisdngondasgjns)已存在。你知道吗

编辑:在peewee错误psycopg2引发此错误之前:

唯一性冲突:重复的键值违反唯一约束“user\u username\u key” 详细信息:Key(username)=(9sdnfsudngfisdngondasgjns)已存在。你知道吗


Tags: selfapiidjsondefaultreturntitlemodels
1条回答
网友
1楼 · 发布于 2024-09-27 21:26:46

这真的很奇怪,但我发现了。我必须更新我的put方法,使其与delete方法的语法相同。基本上,我必须将上下文传递给实际的更新方法:


@marshal_with(blogpost_fields)
    @auth.login_required
    def put(self, id):
        args = self.reqparse.parse_args()
        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.update(**args).where(models.BlogPost.id==id)
            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')}

相关问题 更多 >

    热门问题