如何将 .sql 或 .csv 文件导入 SQLite 数据库?

119

我需要将一个 .sql 或者 .csv 文件导入到 SQLite 中(我正在使用 SQLite3 API)。我只能找到导入/加载表的文档,而没有找到导入整个数据库的文档。目前,当我输入以下命令时:

sqlite3prompt> .import FILENAME TABLE 

我得到了一个语法错误,因为它期望的是一个表而不是整个数据库。


相关文档:[http://www.sqlite.org/cli.html#csv_import] - alttag
11个回答

172

要从一个 SQL 文件中导入数据,请使用以下代码:

sqlite> .read <filename>

要从CSV文件导入数据,您需要指定文件类型和目标表:

sqlite> .mode csv <table>
sqlite> .import <filename> <table>

2
这是正确的答案,但有时它会在奇怪/损坏的 CSV 文件上失败。 - Eli
在使用“.read”命令时,出现“无法打开db.sql”错误。 - Dory
2
如果CSV文件中没有列名,它如何获取列名? - sumanth232
根据文档,如果表不存在,则CSV的第一行将被用作列名;如果该表已经存在,则所有行都会被视为数据。@krishna222 - alttag

25

尝试从命令行执行:

cat dump.sql | sqlite3 database.db

这显然只适用于dump.sql中的SQL语句。我不知道如何导入CSV文件。


我认为这个方法同样有效,但用户必须确保sqlite3设置已经配置为.mode csv - FilBot3
只是想在这里发表一下评论,这实际上是100%准确的,“sqlite3 database.db < dump.sql”非常慢!!!因此最好使用“cat dump.sql | sqlite3 database.db”代替! :D - Javier Buzzi
2
@JavierBuzzi:抱歉,但那没有任何意义。这两种方法是等效的。当您尝试其中一种方法时,您必须还有其他问题。在稳定的测试条件下,我保证不会有速度差异。 - IcarusNM
小心处理这个问题,我的.sql文件顶部没有加载PRAGMA命令。 - undefined

23

从零开始使用SQLite DB到将CSV导入表格:

  • 从官网获取SQLite。
  • 在命令提示符下运行sqlite3 <your_db_file_name> *将创建一个空文件。
  • 在新数据库中创建一个新表。该表必须与您要导入的CSV字段匹配。
  • 您可以通过SQL命令执行此操作:CREATE TABLE <table_Name> (<field_name1> <Type>, <field_name2> <type>);

一旦您创建了表格并且列与文件中的数据匹配,那么您就可以执行以上步骤...

.mode csv <table_name>
.import <filename> <table_name>

@jacob 只是提醒一下,这个答案已经有将近4年的历史了,而且发布者已经三年没有出现在这里了。 - Andrew Barber
1
你救了我好几周的时间。我只用了3秒就完成了我的工作。我仅用5秒就将120MB的CSV文件转换为.db文件。 - zackygaurav

12

sqlite3 .import 命令无法处理普通的 CSV 数据,因为即使在引号字符串中,它也将任何逗号视为分隔符。

这包括尝试重新导入由 shell 创建的 CSV 文件:

Create table T (F1 integer, F2 varchar);
Insert into T values (1, 'Hey!');
Insert into T values (2, 'Hey, You!');

.mode csv
.output test.csv
select * from T;

Contents of test.csv:
1,Hey!
2,"Hey, You!"

delete from T;

.import test.csv T
Error: test.csv line 2: expected 2 columns of data but found 3

看起来我们必须将csv转换成一系列插入语句的列表,或者也许使用不同的分隔符会起作用。

在SuperUser上,我看到了使用LogParser处理csv文件的建议,我要研究一下。


1
blairxy:你遇到的错误是因为“Hey, You!”中有逗号。在加载第二行Sqlite时,它看到了3列,并且在删除第二个逗号后,你就可以无错误地加载它了。 - Shiva

11
如果您乐意使用(Python)脚本,可以使用 Python 脚本自动化此过程:https://github.com/rgrp/csv2sqlite。这将为您自动创建表,并为您执行一些基本的类型猜测和数据转换,例如它将确定某些内容是数字,并将列类型设置为“实数”。

几乎可以使用——标题行导入正常。然而,接下来我遇到了 sqlite3.ProgrammingError: 除非您使用能够解释8位字节串的 text_factory(如 text_factory = str),否则不要使用8位字节串。强烈建议您将应用程序转换为Unicode字符串 # csv2sqlite.py {csv文件路径} {sqlite数据库路径} [{表名}] - Marcos
嗯,我从未在使用此过程中遇到过那个错误。您是否使用非 Unicode 或非 UTF8 数据?如果是这样,您可能需要调整脚本以使用特定编码打开 CSV 文件。 - Rufus Pollock
大约在同一时间,我写了一个Ruby脚本来完成相同的事情!它甚至可以同时处理多个CSV文件,并从文件名猜测表名。https://github.com/dergachev/csv2sqlite - Dergachev
我们需要从sys.stdin读取,因为我们需要转换一个60GB的csv.gz文件。或者,有没有可能将gzip读取支持加入到csv2sqlite中?谢谢! - markusN
@markusN 在 Github 追踪器上开一个问题。一般来说,我会担心在 sqlite 中处理 100GB+ 的 CSV 文件(你考虑过使用“适当的”关系型数据库,例如 postgres 或者 bigquery、redshift 等吗?)。 - Rufus Pollock

7

2

请查看termsql。https://gitorious.org/termsql https://gitorious.org/termsql/pages/Home

它可以在命令行上将文本转换为SQL。(CSV只是文本)

例如:

cat textfile | termsql -o sqlite.db

默认情况下,分隔符是空格,所以要使其适用于使用逗号的CSV文件,您需要这样做:

cat textfile | termsql -d ',' -o sqlite.db

或者您可以这样做:

termsql -i textfile -d ',' -o sqlite.db

默认情况下,它会生成列名“COL0”,“COL1”,如果您想要使用第一行作为列名,可以执行以下操作:

termsql -i textfile -d ',' -1 -o sqlite.db

如果您想设置自定义列名,可以按照以下步骤进行操作:
termsql -i textfile -d ',' -c 'id,name,age,color' -o sqlite.db

1
这是如何向标识列插入数据的方法:
CREATE TABLE my_table (id INTEGER PRIMARY KEY AUTOINCREMENT, name COLLATE NOCASE);
CREATE TABLE temp_table (name COLLATE NOCASE);

.import predefined/myfile.txt temp_table 
insert into my_table (name) select name from temp_table;

myfile.txt是位于C:\code\db\predefined\的文件。

data.db位于C:\code\db\中。

myfile.txt包含由换行符分隔的字符串。

如果您想添加更多列,最好使用竖线字符进行分隔,这是默认设置。


1

SQLite非常灵活,因为它还允许在SQL语法中使用SQLite特定的dot命令(尽管它们由CLI解释)。这意味着您可以做像这样的事情。

创建一个名为sms的表,如下所示:

# sqlite3 mycool.db '.schema sms'
CREATE TABLE sms (_id integer primary key autoincrement, Address VARCHAR, Display VARCHAR, Class VARCHAR, ServiceCtr VARCHAR, Message VARCHAR, Timestamp TIMESTAMP NOT NULL DEFAULT current_timestamp);

然后是两个文件:

# echo "1,ADREZZ,DizzPlay,CLAZZ,SMSC,DaTestMessage,2015-01-24 21:00:00">test.csv

# cat test.sql
.mode csv
.header on
.import test.csv sms

要测试使用SQL文件导入CSV文件,请运行:

# sqlite3 -csv -header mycool.db '.read test.sql'

总之,这意味着您可以在SQLite SQL中使用.import语句,就像在其他RDB(如使用LOAD DATA INFILE的MySQL)中一样。然而,这并不推荐使用。

1

如果您在Windows中使用它,请确保在""中添加到数据库的路径,并且在路径中使用双斜杠\以确保Windows能够理解它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接