【问题标题】:Import CSV file into Sqlite3 Database in command-line or via Batch File在命令行或通过批处理文件将 CSV 文件导入 Sqlite3 数据库
【发布时间】:2011-10-22 02:14:03
【问题描述】:

我想询问是否有将包含我在 SQLite3 中的 select 语句输出的 csv 文件导入新数据库? 以下是我到目前为止所做的代码:

sqlite3.exe -csv logsql.sqlite "SELECT local_port AS port, COUNT(local_port) AS hitcount FROM connections  WHERE connection_type = 'accept' GROUP BY local_port ORDER BY hitcount DESC;" > output.csv
sqlite3.exe -csv test.sqlite "CREATE TABLE test (name varchar(255) not null, blah varchar(255) not null);" .import ./output.csv test

如您所见,我的第一个代码是转储所做的查询。

我正在尝试创建一个新数据库并尝试将 csv 文件导入表“test”的第二行代码

感谢您提前提供的任何帮助! :D

【问题讨论】:

  • 我需要在这里问的一个大问题是:为什么需要这样做?是一次性操作吗,这是程序的一部分吗?
  • 是的,这是程序的一部分。我打算运行批处理脚本来生成我自己的表格,以减少我的 php 程序中图形表示的处理时间

标签: windows csv batch-file import sqlite


【解决方案1】:

我建议您从平面文件中进行导入,这将创建您的架构,然后进行实际导入:

像这样:

sqlite3.exe test.sqlite < import.sql

import.sql 的内容在哪里:

CREATE TABLE test (name varchar(255) not null, blah varchar(255) not null);
.separator ,
.import output.csv test

您可能没有考虑过的另一种方法是ATTACH 命令。您可以附加一个新数据库,在其中创建表,然后导入到它的表中,这样您就没有导出到 CSV 然后重新解析的额外步骤。它可以来自 CREATE TABLE ... AS SELECT ... 查询或只是一个 INSERT。

所以基本上,你会运行(从你的 PHP 页面):

"ATTACH 'c:\directory\to\database\test.db' as TESTDB;"
"CREATE TABLE TESTDB.test AS SELECT local_port AS port, COUNT(local_port) AS hitcount FROM connections  WHERE connection_type = 'accept' GROUP BY local_port ORDER BY hitcount DESC;"

或者:

"ATTACH 'c:\directory\to\database\test.db' as TESTDB;"
"CREATE TABLE TESTDB.test (name varchar(255) not null, blah varchar(255) not null);"
"IMPORT INTO TESTDB.test SELECT local_port AS port, COUNT(local_port) AS hitcount FROM connections  WHERE connection_type = 'accept' GROUP BY local_port ORDER BY hitcount DESC;"

【讨论】:

  • 对不起,我不太明白你的第一段。因为我正在使用批处理脚本。我无法使用 DOT 命令?
  • 非常感谢您的及时回复。他们返回一个错误,说错误:预期 2 列数据,但找到 1 列。是因为我的第一个代码只生成一列吗?我打开了 csv 文件,发现有 2 列已填满。
  • 对不起,我忘了 .import 和 -csv 创建不同的分隔符。请查看我的编辑。
  • 我似乎无法以这种方式针对 sqlite3 数据库运行文件中的脚本 - 它抱怨 Error: incomplete SQL: .separator , .import output.csv items
  • @MichaelForrest items 不是 SQL 命令。如果您需要进一步的帮助,最好提出一个新问题。
【解决方案2】:

一个对我有用的通过 bash 导入文件的单文件命令:

sqlite3 inventory.sqlite.db << EOF
delete from audit;
.separator "\t"
.import audit-sorted-uniq.tsv audit
EOF

希望对您有所帮助。

【讨论】:

    【解决方案3】:

    对于大型 CSV 文件,使用 sqlite3 shell 的 .import 命令可能更有效,而不是在 Python 中解析文件并使用 sqlite3 模块插入行。可以通过os.system 完成(在 Linux、Unix 或 Mac OS X 上,或在 Windows 上的 Cygwin):

    cmd = '(echo .separator ,; echo .import ' + csv_file + ' ' + table + ')'
    cmd += '| sqlite3 ' + db_name
    os.system(cmd)
    

    【讨论】:

      【解决方案4】:

      您可以使用 SQLite 命令外壳和命令行开关做很多事情... ...但我强烈建议您找到一种可在 Windows 上运行并且您感觉舒适的 SQLite 感知脚本语言。

      Perl 和 Python 是两个很好的选择。两者都支持 SqlLite,两者都可免费用于 Windows。

      两者都可以处理这个 - 以及许多其他类型的任务。

      【讨论】:

        【解决方案5】:

        首先,您需要正确的带有逗号分隔符和标题行的真实 csv 文件。 为此,我使用了 phpstorm 的转储工具。

        将所有文件放入一个文件夹中。

        打开 cmd.exe

        创建导入语句,其中 %~na 是不带扩展名的文件名作为表名

        for /R %a in (*.csv) do @echo .import %~na.csv %~na >> import.txt
        

        使用虚拟数据库启动 sqlite

        sqlite test.sqlite
        

        将导入模式设置为 csv

        .mode csv
        

        从文件运行命令

        .read import.txt
        

        列出所有表格

        .tables
        

        退出 sqlite

        .q
        

        【讨论】:

          【解决方案6】:

          我需要导入许多 csv 文件,因此我编写了以下 python 脚本,该脚本执行从 csv 文件创建和加载 sqlite 表的工作,使用 csv 的第一行作为表的字段名称:

          #!/usr/bin/env python
          import sqlite3
          from csv import DictReader
          
          class SQLiteDB():
              def __init__(self, dbname=':memory:'):
                  self.db=sqlite3.connect(dbname)
          
              def importFromCSV(self, csvfilename, tablename, separator=","):
                  with open(csvfilename, 'r') as fh:
                      dr = DictReader(fh, delimiter=separator)
                      fieldlist=",".join(dr.fieldnames)
                      ph=("?,"*len(dr.fieldnames))[:-1]
                      self.db.execute("DROP TABLE IF EXISTS %s"%tablename)
                      self.db.execute("CREATE TABLE %s(%s)"%(tablename, fieldlist))
                      ins="insert into %s (%s) values (%s)"%(tablename, fieldlist, ph)
                      for line in dr:
                          v=[]
                          for k in dr.fieldnames: v.append(line[k])
                          self.db.execute(ins, v)
                  self.db.commit()
          
          if __name__ == '__main__':
              db=SQLiteDB("mydatabase.sqlite")
              db.importFromCSV("mydata.csv", "mytable")
          

          要导入大量数据,应该实现事务。

          【讨论】:

            猜你喜欢
            • 2020-08-17
            • 1970-01-01
            • 2023-01-19
            • 2023-03-16
            • 1970-01-01
            • 1970-01-01
            • 2023-03-11
            • 2014-08-18
            • 1970-01-01
            相关资源
            最近更新 更多