如何在 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()
我正在从网上检索一个 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()