在SQLAlchemy中插入或更新重复键(IntegrityError)

 风云变幻1892_602 发布于 2023-01-08 16:47

我试图解析一些RSS提要并使用URL将URL写入数据库flask-sqlalchemy.

其中一些Feed重叠(即同一篇文章出现在多个Feed中或多次出现在同一个Feed中),因此我将主键定义为URL的(非随机)哈希值.

我的问题是,当我循环遍历URL并将它们添加到Session时,我尝试将它们提交到数据库时遇到异常.

这是我的代码:

for entry in feed.entries:
    # Create the database row
    article = Article(entry)

    # If the row already exists in the database
    if db.session.query(Article).filter_by(uuid=article.uuid).first():
        print "duplicate"
    else:
        db.session.merge(article)

db.session.commit()

当文章已存在于数据库中时,将忽略该文章.但是,如果它存在于Session中但尚未提交数据库,那么SQLAlchemy会尝试在同一事务中多次写入它,我得到了sqlalchemy.exc.IntegrityError: (IntegrityError) column hash is not unique.

我的直觉是我需要检查会话中是否已存在具有该哈希的对象(以及查询数据库),我认为这是合并会做的,但我仍然得到错误.

1 个回答
  • 您应该使用示例中的唯一对象模式.

    这将为会话创建内存缓存,并保证一个唯一的结果.如果实例在缓存中,请使用它,否则尝试从数据库中获取它.如果它不在数据库中,请创建它.将实例添加到缓存中.

    这是我对模式的看法,它简化了链接的例子.

    class UniqueMixin(object):
        @classmethod
        def get_unique(cls, **kwargs):
            session = current_app.extensions['sqlalchemy'].db.session
            session._unique_cache = cache = getattr(session, '_unique_cache', {})
            key = (cls, tuple(kwargs.items()))
            o = cache.get(key)
    
            if o is None:
                o = session.query(cls).filter_by(**kwargs).first()
    
                if o is None:
                    o = cls(**kwargs)
                    session.add(o)
    
                cache[key] = o
    
            return o
    
    class MyModel(UniqueMixin, db.Model):
        # ...
        name = db.Column(db.String, nullable=False)
        # ...
    
    m1 = MyModel.get_unique(name='test')  # new instance
    m2 = MyModel.get_unique(name='test')  # from cache
    assert m1 is m2
    db.session.commit()  # inserts one row
    
    m1 = MyModel.get_unique(name='test')  # from database
    m2 = MyModel.get_unique(name='test')  # from cache
    assert m1 is m2
    

    在可能遇到这种情况的任何模型中继承UniqueMixin,并使用get_unique而不是普通的构造函数.

    2023-01-08 16:48 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有