【问题标题】:SQLITE3: Merge several sqlite3 files in a single oneSQLITE3:将多个 sqlite3 文件合并到一个文件中
【发布时间】:2020-05-10 18:27:42
【问题描述】:

我有许多不同的 .sqlite 数据库文件(大约 1000 个,甚至更多),都具有相同的架构,我需要将它们全部合并到两个 sqlite 文件中,如下所述。

文件名是 "con_cookies_{domain.TLD}.sqlite""sin_cookies_{domain.TLD}.sqlite" em> 所以我想要 "con_cookies.sqlite""sin_cookies.sqlite" >.

最好的方法是什么?我对 sqlite 了解不多,因此不胜感激。

编辑:

我与数据库结构共享一个屏幕截图。如果保留数据的顺序,则主键并不重要。另一方面,每个文件大约有 40-50 行。

DB structure from source files Some SELECT {...} FROM rows example from source

更新:文本格式的数据库架构

id INTEGER PRIMARY KEY, 
baseDomain TEXT, 
originAttributes TEXT NOT NULL DEFAULT '', 
name TEXT, 
value TEXT, 
host TEXT, 
path TEXT, 
expiry INTEGER, 
lastAccessed INTEGER, 
creationTime INTEGER, 
isSecure INTEGER, 
isHttpOnly INTEGER, 
inBrowserElement INTEGER DEFAULT 0, 
sameSite INTEGER DEFAULT 0, 
Domain TEXT, 
DurationDays INTEGER, 
WebCategory TEXT, 
CookieCategory TEXT, 
Action TEXT, 
TLD TEXT, 
CMP_VENDOR TEXT, 
CMP_IAB_V1 TEXT, 
CMP_IAB_V2 TEXT, 
Country TEXT, 
CookiesByDefault, 
CONSTRAINT moz_uniqueid UNIQUE (name, host, path, originAttributes));
CREATE INDEX moz_basedomain ON moz_cookies (baseDomain, originAttributes);

此外,如果将所有数据库大量导出到 CSV 更容易,也可以,而不是加入所有数据库。

【问题讨论】:

  • 我们需要查看架构。复杂之处在于您是否需要保留主键和其他每个数据库的唯一值。
  • 就是这样。你提到了两张桌子。
  • @Schwern 所有 sqlite 文件都有两个表,但我只需要完成它们,称为 moz_cookies,它们都是通用的
  • 你的表没有主键?
  • 您应该将表格定义包含为文本(创建表格语句),而不是图像。

标签: bash sqlite


【解决方案1】:

作为替代方案,请考虑基于 bash 的解决方案。它遍历文件,并将输入表的内容附加到名为“new.sqlite”的新数据库中名为“result”的新表中。

使用 bash SCRIPT con_cookies_*.sqlite 调用

#! /bin/sh -xv
in_table=con_cookie
new_db=new.sqlite

# Start by copying data from first file into table 'result
rm -f $new_db
sqlite3 $new_db <<__SQL__
attach database '$1' as 'data'  ;
create table result as select * from $in_table ;
__SQL__

shift
for file ; do
    echo "Loading $file"
    sqlite3 $new_db <<__SQL__
    attach database '$file' as data ;
    insert into result select * from $in_table ;
__SQL__
done

【讨论】:

    【解决方案2】:

    没有办法保留 id。如果有任何事情取决于 id,这将不起作用。您必须先添加一个globally unique id,改为使用它,然后迁移。

    最简单的做法是创建一个具有自动递增主键的新数据库,然后将每个数据库导入其中,跳过 ID。在 SQLite 中,integer primary key is an alias for the rowid。这足以使其自动递增。通常你会通过转储除 ID 列之外的表来做到这一点,但 SQLite 内置的转储和加载工具是乏善可陈的。

    相反,我们可以编写一个连接到每个数据库的应用程序,跳过 ID 加载每一行,并将其插入到主数据库中。将分配一个新的 ID。这不是最快的,但一次性应该没问题。

    -- Recreate the database in your new table.
    create table moz_cookies (
      id integer primary key, -- this will autoincrement
      ...and all the rest...
    )
    

    然后在程序中循环遍历每个文件,选择每一行,并将除 ID 之外的所有内容插入到新的主表中。

    这是一个使用 sqlite3-ruby 的 Ruby 示例程序。

    require "sqlite3"
    require 'pry'
    
    # The file you're merging to.
    MASTER_FILE = 'con_cookies.sqlite'.freeze
    
    # The pattern to match the files you're pulling from.
    DIR_GLOB = 'con_cookies_*.sqlite'.freeze
    
    # All the columns except ID
    COLS = ['baseDomain', 'originAttributes'].freeze
    
    # A bind string for all the columns
    BINDS = COLS.map { "?" }.join(",").freeze
    
    # The table you're transferring.
    TABLE = 'moz_cookies'.freeze
    
    # Connect to the master database.
    master = SQLite3::Database.new(MASTER_FILE)
    
    # Prepare the insert statement.
    # insert into moz_cookies ('baseDomain', 'originAttributes') values (?,?)
    master.prepare("insert into #{TABLE} (#{COLS.join(",")}) values (#{BINDS})") do |insert_stmt|
      # Find each database file
      Dir.glob(DIR_GLOB) do |file|
        puts "Connecting to #{file}"
    
        # Connect to it
        db = SQLite3::Database.new(file)
    
        # select baseDomain, originAttributes from moz_cookies
        db.prepare("select #{COLS.join(",")} from #{TABLE}") do |select_stmt|
          # Fetch each row...
          rows = select_stmt.execute
          rows.each do |row|
            # Insert into the master table. It will fill in a new ID.
            insert_stmt.execute(row)
          end
        end
      end
    end
    

    请注意,任何需要由 TLD 选择的查询的性能都可能会受到影响。如果您经常这样做,您可能需要制作包含 TLD 的composite indexes。或者你可以迁移到a more powerful database which features table partitioning

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多