IntegrityError错误

本文记录了一次使用Python操作SQLite3数据库时遇到的IntegrityError错误,并详细解析了错误原因及解决方法。作者在尝试插入数据时未正确设置非空字段导致插入失败。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   Python插入数据库提交失败,一直走IntegrityError错误,没打印错误信息(一定注意编码规范,记住打印错误信息),以为插不进去,弄了好久,最后打印了错误信息

 

(sqlite3.IntegrityError) samples.file_type may not be NULL [SQL: u'INSERT INTO samples (file_size, file_type, md5, crc32, sha1, sha256, sha512, ssdeep) VALUES (?, ?, ?, ?, ?, ?, ?, ?)'] [parameters: (53, None, 'hello', 'crc32', 'sha1', 'sha256', 'sha512', None)]

 

  提示为file_type不能为空,但是我建表的时候file_type设置的是不允许为空,而插入的时候file_type传入为NULL,所以Insert不成功,报错IntegrityError

from sqlalchemy import Column, Integer, String
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Text, Index
from sqlalchemy.exc import SQLAlchemyError, IntegrityError
from sqlalchemy.orm import sessionmaker

Base = declarative_base()


class Sample(Base):
    """Submitted files details."""
    __tablename__ = "samples"

    id = Column(Integer(), primary_key=True)
    file_size = Column(Integer(), nullable=False)
    file_type = Column(Text(), nullable=False)
    md5 = Column(String(32), nullable=False)
    crc32 = Column(String(8), nullable=False)
    sha1 = Column(String(40), nullable=False)
    sha256 = Column(String(64), nullable=False)
    sha512 = Column(String(128), nullable=False)
    ssdeep = Column(String(255), nullable=True)
    __table_args__ = Index("hash_index", "md5", "crc32", "sha1",
                           "sha256", "sha512", unique=True),

    def __repr__(self):
        return "<Sample('{0}','{1}')>".format(self.id, self.sha256)


    def __init__(self, md5, crc32, sha1, sha256, sha512,
                 file_size, file_type=None, ssdeep=None):
        self.md5 = md5
        self.sha1 = sha1
        self.crc32 = crc32
        self.sha256 = sha256
        self.sha512 = sha512
        self.file_size = file_size
        if file_type:
            self.file_type = file_type
        if ssdeep:
            self.ssdeep = ssdeep
			
engine = create_engine("sqlite:///cuckoo.db",echo=True)   #返回连接引擎

metadata = Base.metadata
metadata.create_all(engine)  #连接或者创建

			
#sample_mike = Sample("hello", "crc32", "sha1", "sha256", "sha512", 53, None, None)  #非空数据不能传空
sample_mike = Sample("hello", "crc32", "sha1", "sha256", "sha512", 53, "aa", None)
Session = sessionmaker(bind=engine) session = Session() session.add(sample_mike)  #数据库会话
try:
  session.commit() #提交
except IntegrityError as e:
  print e
except SQLAlchemyError as e:
  print e

  

最后在网上看到一个比较有用的工具sqlite,查看db数据库

 

sqlite、db、insert.py下载     http://files.cnblogs.com/files/aliflycoris/db.zip

转载于:https://www.cnblogs.com/aliflycoris/p/5748393.html

<think>嗯,用户问的是关于SQLite3的IntegrityError,特别是UNIQUE约束失败的问题。首先,我需要回忆一下SQLite中的UNIQUE约束是什么,以及触发这个错误的情况。 用户之前已经问过关于分块读取数据的问题,现在转向数据库错误,可能是他们在处理数据导入或更新时遇到了这个问题。可能的情况是,他们正在将分块处理后的数据写入SQLite数据库,但遇到了唯一性冲突。 首先,需要解释这个错误的含义:当尝试插入或更新数据时,违反了表中的一个或多个UNIQUE约束,即重复的值被插入到应该有唯一值的列中。 接下来,我需要分解这个错误的结构。错误信息是(sqlite3.IntegrityError) UNIQUE constraint failed:,后面通常会跟着具体的列名,比如users.email,这能帮助用户定位到哪个列导致了问题。 然后,要考虑用户可能的场景。例如,他们可能在批量导入数据,或者在处理数据时生成了重复的值。比如,用户表中email字段设置了UNIQUE约束,但导入的数据中有重复的邮箱地址,导致插入失败。 需要给出示例代码来说明问题是如何发生的。比如,创建表时定义了UNIQUE约束,然后在插入重复数据时触发错误。这样用户能更直观地理解。 接下来,要分析导致此错误的常见原因:重复插入、批量导入忽略检查、并发写入等。然后给出解决方案,比如在插入前检查是否存在,使用INSERT OR IGNORE,或者利用事务处理。 还要注意,用户可能对SQLite不熟悉,所以需要详细解释每个解决方案的适用场景,并给出代码示例。例如,使用ON CONFLICT子句来处理冲突,或者使用事务来批量处理避免部分失败。 此外,用户可能是在处理分块数据时遇到这个问题,所以需要结合之前的chunk处理,建议他们在处理每个chunk时检查唯一性,或者在数据库层面处理冲突。 最后,总结注意事项,比如索引的影响、错误处理的重要性,以及如何调整约束策略。确保用户理解如何预防和解决这类问题,特别是在大数据量分块处理时的最佳实践。</think>好的,我将分步解释 `(sqlite3.IntegrityError) UNIQUE constraint failed:` 这个错误的含义、触发场景和解决方案: --- ### **1. 错误本质** 这是SQLite数据库抛出的完整性约束错误,表示**试图插入或更新的数据违反了表的唯一性约束**。当某个字段(或字段组合)被定义为`UNIQUE`,但操作导致该字段出现重复值时触发。 --- ### **2. 错误结构解析** 完整错误信息通常形如: ```python sqlite3.IntegrityError: UNIQUE constraint failed: 表名.字段名 # 示例:UNIQUE constraint failed: users.email ``` - `users`:触发约束的表名 - `email`:被`UNIQUE`约束的字段 --- ### **3. 典型触发场景** #### **场景示例表结构** ```sql CREATE TABLE users ( id INTEGER PRIMARY KEY, email TEXT UNIQUE, -- 唯一性约束 username TEXT UNIQUE -- 组合唯一性约束 ); ``` #### **触发案例** ```python # 第一次插入成功 cursor.execute("INSERT INTO users (email) VALUES ('test@example.com')") # 第二次插入相同email时触发错误 cursor.execute("INSERT INTO users (email) VALUES ('test@example.com')") # 抛出 IntegrityError: UNIQUE constraint failed: users.email ``` --- ### **4. 常见原因分类** | 原因类型 | 具体场景 | |---------|---------| | **直接重复插入** | 明文插入已存在的唯一值 | | **批量导入疏漏** | CSV导入时未去重 | | **并发写入冲突** | 多线程/多进程同时插入相同值 | | **逻辑错误** | 程序生成的ID/哈希值意外重复 | --- ### **5. 解决方案** #### **(1) 预查重策略** ```python email = 'test@example.com' # 先查询是否存在 cursor.execute("SELECT 1 FROM users WHERE email = ?", (email,)) if not cursor.fetchone(): cursor.execute("INSERT INTO users (email) VALUES (?)", (email,)) else: print(f"Email {email} 已存在") ``` #### **(2) 使用冲突处理子句** ```sql -- 忽略冲突 INSERT OR IGNORE INTO users (email) VALUES ('test@example.com'); -- 替换已有数据 INSERT OR REPLACE INTO users (email) VALUES ('test@example.com'); -- 自定义冲突处理(SQLite 3.24.0+) INSERT INTO users (email) VALUES ('test@example.com') ON CONFLICT(email) DO UPDATE SET email=excluded.email; ``` #### **(3) 事务批量处理优化** ```python try: with sqlite3.connect('db.sqlite') as conn: conn.execute("BEGIN TRANSACTION") # 开启事务 # 批量插入操作 conn.executemany("INSERT OR IGNORE INTO users (email) VALUES (?)", email_list) conn.commit() except sqlite3.IntegrityError as e: conn.rollback() print(f"批量插入失败: {e}") ``` --- ### **6. 调试建议** 1. **定位具体字段** 通过错误信息中的`表名.字段名`确定哪个字段引发冲突 2. **数据溯源** 打印触发异常的SQL语句和数据: ```python print(f"问题SQL: {cursor.last_query}") # 需要记录执行的SQL print(f"问题数据: {data}") # 显示触发冲突的具体值 ``` 3. **数据库验证** 直接查询冲突值: ```sql SELECT * FROM 表名 WHERE 冲突字段 = '冲突值'; ``` --- ### **7. 设计注意事项** - **组合唯一约束**:多个字段共同构成唯一约束时(如`UNIQUE(col1, col2)`),需检查字段组合 - **索引影响**:`UNIQUE`约束会自动创建索引,大数据量时可能影响写入性能 - **错误处理必要性**:必须用`try-except`捕捉`sqlite3.IntegrityError` - **约束策略选择**:根据业务需求选择`UNIQUE`、`PRIMARY KEY`或自定义冲突解决逻辑 --- 通过这种分层处理方案,既可以保证数据完整性,又能根据业务需求灵活处理重复数据问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值