如果指定了 unique=True
的列,那么在插入数据的时候,如果值重复了,sqlite 就会报错,如果想忽略这个冲突,那么就可以使用下面的几个方法。
方法一:在定义 table 的时候指定 IGNORE
参考:https://docs.sqlalchemy.org/en/14/dialects/sqlite.html
联合住键
some_table = Table(
'some_table', metadata,
Column('id', Integer, primary_key=True),
Column('data', Integer),
UniqueConstraint('id', 'data', sqlite_on_conflict='IGNORE')
)
相当于如下SQL语句
CREATE TABLE some_table (
id INTEGER NOT NULL,
data INTEGER,
PRIMARY KEY (id),
UNIQUE (id, data) ON CONFLICT IGNORE
)
单键
some_table = Table(
'some_table', metadata,
Column('id', Integer, primary_key=True),
Column('data', Integer, unique=True,
sqlite_on_conflict_unique='IGNORE')
)
相当于如下SQL语句
CREATE TABLE some_table (
id INTEGER NOT NULL,
data INTEGER,
PRIMARY KEY (id),
UNIQUE (data) ON CONFLICT IGNORE
)
或者
class Config(Base):
__tablename__ = "config"
__table_args__ = (sqlalchemy.UniqueConstraint('schema','key', sqlite_on_conflict='IGNORE'),)
id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True, autoincrement=True)
schema = sqlalchemy.Column(sqlalchemy.String(128), default=None, nullable=True)
key = sqlalchemy.Column(sqlalchemy.String(128), default=None, nullable=True)
value = sqlalchemy.Column(sqlalchemy.String(512), nullable=False)
或者
class Urls(Base):
__tablename__ = "urls"
id = sqlalchemy.Column(sqlalchemy.Integer, primary_key=True, autoincrement=True)
title = sqlalchemy.Column(sqlalchemy.String(512))
url = sqlalchemy.Column(sqlalchemy.String(1024), nullable=False, unique=True, sqlite_on_conflict_unique='IGNORE')
addtime = sqlalchemy.Column(sqlalchemy.DateTime(), default=datetime.datetime.now, nullable=False)
方法二:在执行 SQL 的时候指定 IGNORE
参考:https://stackoverflow.com/questions/2218304/sqlalchemy-insert-ignore
- prefix_with("OR REPLACE")
inserter = table_object.insert().prefix_with("OR REPLACE")
inserter.execute([{'column1':'value1'}, {'column1':'value2'}])
- use a compiler extension
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.sql.expression import Insert
#
@compiles(Insert)
def _prefix_insert_with_ignore(insert, compiler, **kw):
return compiler.visit_insert(insert.prefix_with('OR IGNORE'), **kw)
OR
from sqlalchemy.ext.compiler import compiles, deregister
from sqlalchemy.sql.expression import Insert
#
def _prefix_insert_with_ignore(insert, compiler, **kw):
return compiler.visit_insert(insert.prefix_with('OR IGNORE'), **kw)
#
compiles(Insert)(_prefix_insert_with_replace)
try:
# do some inserts...
finally:
deregister(Insert)
方法三:在 sql 语句中使用 IGNORE
参考:https://stackoverflow.com/questions/35415469/sqlite3-unique-constraint-failed-error
INSERT or IGNORE into tablename VALUES (value1,value2 , so on );
或者
INSERT or REPLACE into tablename VALUES (value1,value2 , so on );