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

时间:2015-02-18 18:34:27

标签: python mysql sql-insert unique-constraint peewee

我正在使用peewee从在线检索我要插入数据库的json文件。问题是我的数据库中可能已存在某些行。解决方案应该是忽略或替换重复的行。

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'

这不会产生任何错误,并成功添加了一个'和'两个'到我的桌子。

如果我再跑,

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

执行功能会抛出一个错误,而且三个'或者四个'被添加到数据库中。

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

3 个答案:

答案 0 :(得分:2)

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

on_conflict()将使用给定的参数添加SQL ON CONFLICT子句,但仅适用于SQLite。 upsert()基本上将查询转换为MySQL上的REPLACE INTO。您仍然需要在{。<}后调用execute()

答案 1 :(得分:1)

我无法在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

给了我很大的帮助

答案 2 :(得分:1)

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

peewee doc upsert