如何在 peewee 中使用 INSERT REPLACE 插入多行?

How can I insert multiple rows with INSERT REPLACE in peewee?

我正在从网上检索一个 json 文件,我想使用 peewee 将其插入到我的数据库中。问题是某些行可能已经存在于我的数据库中。解决方案应该是忽略或替换重复的行。

InsertQuery 函数支持添加多行,但我不知道如何抑制实例已存在的错误或替换现有实例。

从空数据库测试开始,我运行下面的代码

from peewee import *
from peewee import InsertQuery

database = MySQLDatabase('test', **{'password': 'researchServer', 'user': 'root'})

class BaseModel(Model):
    class Meta:
        database = database

class Image(BaseModel):
    url = CharField(unique=True)

database.connect()
database.create_tables([Image])
images= [{'url': 'one'}, {'url':'two'}]
try:
    image_entry = InsertQuery(Image, rows=images)
    image_entry.execute()
except:
    print 'error'

这不会产生任何错误并成功将 'one' 和 'two' 添加到我的 table。

如果我那么运行,

images= [{'url':'three'}, {'url': 'one'}, {'url':'four'}]
try:
    image_entry = InsertQuery(Image, rows=images)
    image_entry.execute()
except:
    print 'error'

执行函数抛出错误,'three' 或 'four' 都没有添加到数据库中。

我想一个解决方案是在将每一行添加到数据库之前检查它,但这似乎效率更低。

我无法在 peewee 中找到解决方案,但这是我为 SQLAlchemy 编写的解决方案。

from sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKey
from sqlalchemy import create_engine

#Make the table
metadata = MetaData()
image = Table('image', metadata,
              Column('url', String(250), primary_key=True))

db = create_engine('mysql://root:researchServer@localhost/test3')
metadata.create_all(db)

conn = engine.connect()

#Insert the first set of rows
images = [{'url': 'one'}, {'url': 'two'}]
inserter = db.image.insert()
conn.execute(inserter, images)

#Insert the second set of rows with some duplicates
images = [{'url': 'three'}, {'url': 'one'}, {'url':'four'}]
try:
    inserter = db.image.insert().prefix_with("IGNORE")
    conn.execute(inserter, images)
except:
    print 'error'

关键是使用'prefix_with'方法将'ignore'添加到SQL表达式中。 SQLAlchemy INSERT IGNORE

对我帮助很大

您可以在 InsertQuery 上使用 on_conflict() or upsert()

on_conflict() 将添加带有给定参数的 SQL ON CONFLICT 子句,但仅适用于 SQLite。 upsert() 基本上将查询变成 MySQL 上的 REPLACE INTO。您仍然需要在之后调用 execute()

Image.insert_many(images).upsert(True).execute()

peewee doc upsert