Python的SQLite3数据库的256000字节限制

时间:2015-07-07 09:40:52

标签: python sqlite

我编写了一个网络抓取工具,可以进行一些在线预处理并将数据存储到数据库中。数据库布局非常简单,但让我概述一下:

  • dispatched列出了在特定时间调度的项目,这是其中一列。还有15个其他列描述了这些项:其中一列来自TEXT类型,其余来自类型INT
  • missed列出了抓取工具无法观看的时间段,例如因为网络问题。它有INT类型的4列和TEXT类型的2列。

我让它跑了两个小时。两次,生成的数据库文件的总大小恰好为256000字节,至少根据ls -l。我从记录的数据中看到,每分钟定期记录1-3项,但从特定时间开始,不再列出任何新项目。

对我来说,这听起来好像我遇到了限制。鉴于生成的数据库文件大小两次都是1000 * 2^8字节,我怀疑这是对最大数据库文件大小的限制,但documentation并没有这样说。

当SQLite停止向数据库添加新行时,有

    第一次运行期间,
  • dispatched上的5187行和missed上的3行
  • 第二次运行期间dispatched上的5212行和missed上的2行。

我正在使用Python {的sqlite3模块。我感谢任何可能指出发生了什么的帮助,为什么SQLite在达到256000字节后停止追加新行以及如何解决这个问题。

更新:我已决定从我的代码中添加一些代码段。

应用程序包含由名为Gatherer的类计划和执行的任务。首先,让我们看看这里感兴趣的任务:

class ControlTask(Task):

    def __init__(self, player, scheduled_start):
        Task.__init__(self, scheduled_start)
        self.player = player

    def __str__(self):
        return u'CONTROL: player %d' % self.player.player_id

    def execute(self, gt):
        # [...]
        gt.dispatch(self.player)
        # [...]

当时间到来时,Gatherer会在每项任务上调用execute,通过gt参数提供对自身的引用:

class Gatherer:

    def process_next_task(self):
        task = self.tasks.get()
        while True:

即使在SQLite停止追加行之后,我也可以看到这些消息:

            print task.__str__()

但我没有看到以下错误消息。此外,请注意,此循环不会退出,直到任务完成而没有异常

            try:
                task.execute(self)
                break
            except engine.NetworkException:
                print 'NETWORK PROBLEM DETECTED. Reconnecting.'
                self.reconnect()
            except:
                print 'UNKNOWN EXCEPTION OCCURED. Reconnecting.'
                self.reconnect()

    def reconnect(self):
        # [...]

ControlTaskdispatch上调用Gatherer,然后将任务计算的数据写入数据库:

    def dispatch(self, player):
        self.db_cursor.execute('''INSERT INTO dispatched VALUES
            (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''', (\
                None, player.deadline, player.age, player.tsi, \
                player.speciality, player.skills[0], player.skills[1], \
                player.skills[2], player.skills[3] , player.skills[4], \
                player.skills[5], player.skills[6], player.skills[7], \
                player.skills[8], player.skills[9], player.skills[10]))
        self.db.commit()

Gatherer在实例化时创建数据库,并在垃圾回收时关闭数据库连接:

    def __init__(self):
        self.tasks = Queue.PriorityQueue()

        self.db = sqlite3.connect('%s.db' % time.strftime('%d.%m.%Y %H:%M'))
        self.db_cursor = self.db.cursor()

        self.db_cursor.execute('''CREATE TABLE IF NOT EXISTS dispatched (
            amount int, deadline int, age int, tsi int, speciality text,
            s1 int, s2 int, s3 int, s4 int, s5 int, s6 int,
            s7 int, s8 int, s9 int, s10 int, s11 int)''')

        self.db_cursor.execute('''CREATE TABLE IF NOT EXISTS missed (
            missed_from int, missed_until int,
            min_age int, max_age int,
            min_lvl int, max_lvl int)''')

    def __del__(self):
        self.db.close()

最后,这是实际的程序:

if __name__ == '__main__':

    gt = Gatherer()

    tasks_processed = 0
    while True:
        print 'Starting %d. task while %d are enqueued:' % \
            (tasks_processed+1, gt.tasks.qsize())
        try:
            gt.process_next_task()
        except KeyboardInterrupt:
            break
        except:
            del gt
            raise
        tasks_processed = tasks_processed + 1

0 个答案:

没有答案