【问题标题】:Continue loading after IntegrityErrorIntegrityError 后继续加载
【发布时间】:2011-03-13 19:52:35
【问题描述】:

在 python 中,我使用 importmany 填充 SQLITE 数据库,因此我可以一次导入数万行数据。我的数据包含在元组列表中。我用我想要的主键设置了我的数据库。

我遇到的问题是主键错误会引发 IntegrityError。如果我处理异常,我的脚本会在主键冲突时停止导入。
试试:

try:
    self.curs.executemany("INSERT into towers values (NULL,?,?,?,?)",self.insertList)
except IntegrityError:
    print "Primary key error"
conn.commit()


所以我的问题是,在 python 中使用 importmany 我可以:

1. 捕获违反主键的值?
2. 收到主键错误后继续加载数据。

我明白为什么它没有继续加载,因为在异常之后我将数据提交到数据库。但是,我不知道如何从中断的地方继续。

Unforutnley 我无法复制和粘贴此网络上的所有代码,任何帮助将不胜感激。现在我没有将 PK 设置为解决方法...

【问题讨论】:

    标签: python sql sqlite


    【解决方案1】:

    您可以使用lastrowid 来获取您停止的位置:

    http://docs.python.org/library/sqlite3.html#sqlite3.Cursor.lastrowid

    但是,如果你使用它,你就不能使用executemany

    【讨论】:

      【解决方案2】:

      使用 for 循环遍历列表并使用 execute 而不是 executemany。用你的 try 包围 for 循环,并在异常后继续执行。像这样的:

      for it in self.insertList:
          try:
              self.curs.execute("INSERT into towers values (NULL,?,?,?,?)",it)
          except IntegrityError:
              #here you could insert the itens that were rejected in a temporary table
              #without constraints for later use (question 1)
              pass
      conn.commit()
      

      您甚至可以计算列表中实际插入了多少项。

      【讨论】:

      • 据我了解,executemany 的存在是因为它比 python 迭代的execute 命令显着提高了速度。因此,您的解决方案虽然可行,但会显着减慢大量数据的导入速度。一种解决方案是跟踪已添加到 python 集中的主键,并在将其提供给光标之前提前过滤 insertList。
      • @PeterMcMahan 好的,我同意。这不是有效的代码。它只会像你所说的那样“有效”。
      【解决方案3】:

      先回答(2),如果报错后还想继续加载,在SQL端做个简单的修复:

      INSERT OR IGNORE INTO towers VALUES (NULL,?,?,?,?)
      

      这将成功插入没有任何违规的行,并优雅地忽略冲突。但是请注意,IGNORE 子句仍然会因外键违规而失败。

      在您的情况下,冲突解决子句的另一个选项是:INSERT OR REPLACE INTO ...。我强烈推荐SQLite docs 了解有关冲突和冲突解决的更多信息。

      据我所知,您不能以一种有效的方式同时做到 (1) 和 (2)。您可能会创建一个触发器以在可以捕获冲突行的插入之前触发,但这会给您的所有插入带来很多不必要的开销。 (如果您能以更聪明的方式做到这一点,请告诉我。)因此,如果可能/适用,我建议您考虑是否真的需要捕获冲突行的值,或者是否需要重新设计架构。

      【讨论】:

        猜你喜欢
        • 2019-12-18
        • 2017-09-20
        • 2015-09-03
        • 1970-01-01
        • 2021-08-09
        • 2015-08-17
        • 2019-04-22
        • 2012-06-21
        • 1970-01-01
        相关资源
        最近更新 更多