【问题标题】:Force sqlite3 (on python) to store data sequentially强制 sqlite3(在 python 上)按顺序存储数据
【发布时间】:2020-08-10 03:14:10
【问题描述】:

我将下面给出的代码仅用于两个操作:

  1. 在数据库的最底部插入 numpy 数组
  2. 拉出第一个数组,然后将其删除

我正在处理的数据将非常大(考虑到低 TB)并且我希望数据在我的硬盘驱动器上按顺序存储和检索(就像旧磁带一样贮存)。现在我已经在这片土地上进行了广泛的搜索,我不确定这是否已经在 sqlite3 上自动完成,或者是否可能。

import io
import numpy as np
import sqlite3

class SQLNumpy():
    """This will insert a numpy array into a sqlite3 instance"""
    def __init__(self, db_name):
        # Converts np.array to TEXT when inserting
        sqlite3.register_adapter(np.ndarray, self.adapt_array)
        # Converts TEXT to np.array when selecting
        sqlite3.register_converter("array", self.convert_array)

        self.db_name = db_name
        self.conn = sqlite3.connect(self.db_name, detect_types=sqlite3.PARSE_DECLTYPES)
        self.cursor = self.conn.cursor()
        self.cursor.execute("""CREATE TABLE IF NOT EXISTS data (
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        arr ARRAY);""")

    def adapt_array(self, arr):
        out = io.BytesIO()
        np.save(out, arr)
        out.seek(0)
        return sqlite3.Binary(out.read())

    def convert_array(self, text):
        out = io.BytesIO(text)
        out.seek(0)
        return np.load(out)

    def insert(self, arr):
        self.cursor.execute("INSERT INTO data (arr) values (?)", (arr, ))

    def first_select(self):
        self.cursor.execute("SELECT arr FROM data LIMIT 1")
        self.data = self.cursor.fetchall()

    def first_delete(self):
        self.cursor.execute("""DELETE FROM data WHERE id in (
            SELECT id FROM data LIMIT 1)""")

    def commit(self):
        self.conn.commit()

    def close(self):
        self.conn.close()

x = np.random.rand(8760)

x_sql = SQLNumpy("test.db")
x_sql.insert(x)
x_sql.insert(x) # Add two and then remove one. 

x_sql.first_select()                        
print(x_sql.data)                           
x_sql.first_delete()
                        
x_sql.commit()                              
x_sql.close()                               

【问题讨论】:

  • 这在代码中没有什么可以解决的,很可能在数据库中也没有。如今,在现代驱动器上,甚至操作系统都没有说明数据的确切存储位置。
  • 嗯,有没有办法连接到较低级别的 API 以在 python 上直接访问磁盘?我将在 Ubuntu 服务器上运行我的代码,但可以将其更改为任何提供此服务的 Linux 发行版。
  • 听起来你根本没有阅读我的评论。
  • 我确实阅读了您的评论,这就是为什么我问是否可能有另一个发行版(或操作系统)允许这样做。或者是低级 API,计算机上的某些进程必须知道数据在哪里。

标签: python sql database sqlite numpy


【解决方案1】:

没有 100% 保证的方式来做到这一点。

作为@KlausD。指出,即使是对驱动器的最低软件访问也不能保证任何事情,因为现代磁盘会在软件不知道的情况下移动数据(通常是为了修复损坏的扇区)。

最好的办法是一次性将数据写入一个文件。

(如果你感觉很疯狂,你可以放弃一个文件系统,在 Linux 中,将数据直接写入/dev/sdX 块设备节点,这是你在软件领域最接近连续空间的地方,但是您要么必须非常小心才能正确访问数据,要么浪费大量时间重新发明文件系统)

SQLite 肯定不会帮你解决这个问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-29
    • 2016-09-09
    • 1970-01-01
    • 2015-05-10
    相关资源
    最近更新 更多