如何转储一些SQLite3表的数据?

发布于 2024-07-04 03:55:55 字数 178 浏览 12 评论 0原文

如何转储数据库的某些 SQLite3 表(不是所有表)的数据,并且仅转储数据,而不转储架构? 转储应该采用 SQL 格式,因为稍后应该可以轻松地将其重新输入到数据库中,并且应该从命令行完成。 类似于

sqlite3 db .dump

但不转储架构并选择要转储的表。

How do I dump the data, and only the data, not the schema, of some SQLite3 tables of a database (not all the tables)?
The dump should be in SQL format, as it should be easily re-entered into the database later and should be done from the command line. Something like

sqlite3 db .dump

but without dumping the schema and selecting which tables to dump.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(14

无戏配角 2024-07-11 03:55:55

您没有说明您希望如何处理转储的文件。

获取 CSV 文件(可以导入几乎所有内容)

.mode csv 
-- use '.separator SOME_STRING' for something other than a comma.
.headers on 
.out file.csv 
select * from MyTable;

获取 SQL 文件(可以重新插入到不同的 SQLite 数据库中)

.mode insert <target_table_name>
.out file.sql 
select * from MyTable;

You're not saying what you wish to do with the dumped file.

To get a CSV file (which can be imported into almost everything)

.mode csv 
-- use '.separator SOME_STRING' for something other than a comma.
.headers on 
.out file.csv 
select * from MyTable;

To get an SQL file (which can be reinserted into a different SQLite database)

.mode insert <target_table_name>
.out file.sql 
select * from MyTable;
微凉徒眸意 2024-07-11 03:55:55

您可以通过获取 .schema 和 .dump 命令的差异来执行此操作。 例如,使用 grep:

sqlite3 some.db .schema > schema.sql
sqlite3 some.db .dump > dump.sql
grep -vx -f schema.sql dump.sql > data.sql

data.sql 文件将仅包含没有模式的数据,如下所示:

BEGIN TRANSACTION;
INSERT INTO "table1" VALUES ...;
...
INSERT INTO "table2" VALUES ...;
...
COMMIT;

You can do this getting difference of .schema and .dump commands. for example with grep:

sqlite3 some.db .schema > schema.sql
sqlite3 some.db .dump > dump.sql
grep -vx -f schema.sql dump.sql > data.sql

data.sql file will contain only data without schema, something like this:

BEGIN TRANSACTION;
INSERT INTO "table1" VALUES ...;
...
INSERT INTO "table2" VALUES ...;
...
COMMIT;
不语却知心 2024-07-11 03:55:55

您可以为 .dump 特殊命令指定一个或多个表参数,例如sqlite3 db ".dump 'table1' 'table2'"

You can specify one or more table arguments to the .dump special command, e.g.sqlite3 db ".dump 'table1' 'table2'".

一向肩并 2024-07-11 03:55:55

这不是最好的方法,但至少不需要外部工具(除了 grep,无论如何,这是 *nix 盒子上的标准),

sqlite3 database.db3 .dump | grep '^INSERT INTO "tablename"'

但您确实需要为您要查找的每个表执行此命令。

请注意,这不包括架构。

Not the best way, but at lease does not need external tools (except grep, which is standard on *nix boxes anyway)

sqlite3 database.db3 .dump | grep '^INSERT INTO "tablename"'

but you do need to do this command for each table you are looking for though.

Note that this does not include schema.

吃不饱 2024-07-11 03:55:55

任何建议使用 grep 排除 CREATE 行或仅从 sqlite3 $DB .dump 输出中获取 INSERT 行的答案都将严重失败。 CREATE TABLE 命令每行列出一列(因此排除 CREATE 将无法获得全部内容),并且 INSERT 行上的值可以嵌入了换行符(因此您不能只获取 INSERT 行)。

for t in $(sqlite3 $DB .tables); do
    echo -e ".mode insert $t\nselect * from $t;"
done | sqlite3 $DB > backup.sql

在 sqlite3 版本 3.6.20 上测试。

如果您想排除某些表,您可以使用 $(sqlite $DB .tables | grep -v -e one -e 2 -e 3) 来过滤它们,或者如果您想获取特定的子集将其替换为一二三

Any answer which suggests using grep to exclude the CREATE lines or just grab the INSERT lines from the sqlite3 $DB .dump output will fail badly. The CREATE TABLE commands list one column per line (so excluding CREATE won't get all of it), and values on the INSERT lines can have embedded newlines (so you can't grab just the INSERT lines).

for t in $(sqlite3 $DB .tables); do
    echo -e ".mode insert $t\nselect * from $t;"
done | sqlite3 $DB > backup.sql

Tested on sqlite3 version 3.6.20.

If you want to exclude certain tables you can filter them with $(sqlite $DB .tables | grep -v -e one -e two -e three), or if you want to get a specific subset replace that with one two three.

佞臣 2024-07-11 03:55:55

作为对 Paul Egan 答案的改进,可以按如下方式完成:

sqlite3 database.db3 '.dump "table1" "table2"' | grep '^INSERT'

--或者 --

sqlite3 database.db3 '.dump "table1" "table2"' | grep -v '^CREATE'

当然,需要注意的是您必须安装 grep。

As an improvement to Paul Egan's answer, this can be accomplished as follows:

sqlite3 database.db3 '.dump "table1" "table2"' | grep '^INSERT'

--or--

sqlite3 database.db3 '.dump "table1" "table2"' | grep -v '^CREATE'

The caveat, of course, is that you have to have grep installed.

柠檬色的秋千 2024-07-11 03:55:55

在 Python 或 Java 或任何高级语言中,.dump 不起作用。 我们需要手动编写转换为 CSV 的代码。 我举一个Python的例子。 其他人,示例将不胜感激:

from os import path   
import csv 

def convert_to_csv(directory, db_name):
    conn = sqlite3.connect(path.join(directory, db_name + '.db'))
    cursor = conn.cursor()
    cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
    tables = cursor.fetchall()
    for table in tables:
        table = table[0]
        cursor.execute('SELECT * FROM ' + table)
        column_names = [column_name[0] for column_name in cursor.description]
        with open(path.join(directory, table + '.csv'), 'w') as csv_file:
            csv_writer = csv.writer(csv_file)
            csv_writer.writerow(column_names)
            while True:
                try:
                    csv_writer.writerow(cursor.fetchone())
                except csv.Error:
                    break

如果您有“面板数据”,换句话说,许多带有 id 的单独条目将其添加到 with 外观中,并且它还会转储摘要统计信息:

        if 'id' in column_names:
            with open(path.join(directory, table + '_aggregate.csv'), 'w') as csv_file:
                csv_writer = csv.writer(csv_file)
                column_names.remove('id')
                column_names.remove('round')
                sum_string = ','.join('sum(%s)' % item for item in column_names)
                cursor.execute('SELECT round, ' + sum_string +' FROM ' + table + ' GROUP BY round;')
                csv_writer.writerow(['round'] + column_names)
                while True:
                    try:
                        csv_writer.writerow(cursor.fetchone())
                    except csv.Error:
                        break 

In Python or Java or any high level language the .dump does not work. We need to code the conversion to CSV by hand. I give an Python example. Others, examples would be appreciated:

from os import path   
import csv 

def convert_to_csv(directory, db_name):
    conn = sqlite3.connect(path.join(directory, db_name + '.db'))
    cursor = conn.cursor()
    cursor.execute("SELECT name FROM sqlite_master WHERE type='table';")
    tables = cursor.fetchall()
    for table in tables:
        table = table[0]
        cursor.execute('SELECT * FROM ' + table)
        column_names = [column_name[0] for column_name in cursor.description]
        with open(path.join(directory, table + '.csv'), 'w') as csv_file:
            csv_writer = csv.writer(csv_file)
            csv_writer.writerow(column_names)
            while True:
                try:
                    csv_writer.writerow(cursor.fetchone())
                except csv.Error:
                    break

If you have 'panel data, in other words many individual entries with id's add this to the with look and it also dumps summary statistics:

        if 'id' in column_names:
            with open(path.join(directory, table + '_aggregate.csv'), 'w') as csv_file:
                csv_writer = csv.writer(csv_file)
                column_names.remove('id')
                column_names.remove('round')
                sum_string = ','.join('sum(%s)' % item for item in column_names)
                cursor.execute('SELECT round, ' + sum_string +' FROM ' + table + ' GROUP BY round;')
                csv_writer.writerow(['round'] + column_names)
                while True:
                    try:
                        csv_writer.writerow(cursor.fetchone())
                    except csv.Error:
                        break 
缘字诀 2024-07-11 03:55:55

查看其他可能的解决方案

仅包含 INSERT

sqlite3 database.db3 .dump | grep '^INSERT INTO "tablename"'

易于实现,但如果任何列包含换行符,则会失败

SQLite 插入模式

for t in $(sqlite3 $DB .tables); do
    echo -e ".mode insert $t\nselect * from $t;"
done | sqlite3 $DB > backup.sql

这是一个很好的可自定义解决方案,但它如果您的列在spatialite中具有像“Geometry”类型这样的blob对象,

则不起作用 将转储与模式进行比较

sqlite3 some.db .schema > schema.sql
sqlite3 some.db .dump > dump.sql
grep -v -f schema.sql dump > data.sql

不知道为什么,但对我不起作用

另一个(新的)可能的解决方案

可能没有这个问题的最佳答案,但对我有用的一个是 grep 插入,考虑到列值中带有 像这样的表达式

grep -Pzo "(?s)^INSERT.*\);[ \t]*$"

要选择要转储的表.dump承认LIKE参数来匹配表名称,但如果这还不够,可能一个简单的脚本是更好的选择

TABLES='table1 table2 table3'

echo '' > /tmp/backup.sql
for t in $TABLES ; do
    echo -e ".dump ${t}" | sqlite3 database.db3 | grep -Pzo "(?s)^INSERT.*?\);$" >> /tmp/backup.sql
done

,或者,其他更详细地考虑外键并将所有转储封装在一个事务中

TABLES='table1 table2 table3'

echo 'BEGIN TRANSACTION;' > /tmp/backup.sql
echo '' >> /tmp/backup.sql
for t in $TABLES ; do
    echo -e ".dump ${t}" | sqlite3 $1 | grep -Pzo "(?s)^INSERT.*?\);$" | grep -v -e 'PRAGMA foreign_keys=OFF;' -e 'BEGIN TRANSACTION;' -e 'COMMIT;' >> /tmp/backup.sql
done

echo '' >> /tmp/backup.sql
echo 'COMMIT;' >> /tmp/backup.sql

考虑到如果 ); 是任何列中存在的字符串,则 grep 表达式将失败

要恢复它(在数据库中)与已经创建的表)

sqlite3 -bail database.db3 < /tmp/backup.sql

Review of other possible solutions

Include only INSERTs

sqlite3 database.db3 .dump | grep '^INSERT INTO "tablename"'

Easy to implement but it will fail if any of your columns include new lines

SQLite insert mode

for t in $(sqlite3 $DB .tables); do
    echo -e ".mode insert $t\nselect * from $t;"
done | sqlite3 $DB > backup.sql

This is a nice and customizable solution, but it doesn't work if your columns have blob objects like 'Geometry' type in spatialite

Diff the dump with the schema

sqlite3 some.db .schema > schema.sql
sqlite3 some.db .dump > dump.sql
grep -v -f schema.sql dump > data.sql

Not sure why, but is not working for me

Another (new) possible solution

Probably there is not a best answer to this question, but one that is working for me is grep the inserts taking into account that be new lines in the column values with an expression like this

grep -Pzo "(?s)^INSERT.*\);[ \t]*$"

To select the tables do be dumped .dump admits a LIKE argument to match the table names, but if this is not enough probably a simple script is better option

TABLES='table1 table2 table3'

echo '' > /tmp/backup.sql
for t in $TABLES ; do
    echo -e ".dump ${t}" | sqlite3 database.db3 | grep -Pzo "(?s)^INSERT.*?\);$" >> /tmp/backup.sql
done

or, something more elaborated to respect foreign keys and encapsulate all the dump in only one transaction

TABLES='table1 table2 table3'

echo 'BEGIN TRANSACTION;' > /tmp/backup.sql
echo '' >> /tmp/backup.sql
for t in $TABLES ; do
    echo -e ".dump ${t}" | sqlite3 $1 | grep -Pzo "(?s)^INSERT.*?\);$" | grep -v -e 'PRAGMA foreign_keys=OFF;' -e 'BEGIN TRANSACTION;' -e 'COMMIT;' >> /tmp/backup.sql
done

echo '' >> /tmp/backup.sql
echo 'COMMIT;' >> /tmp/backup.sql

Take into account that the grep expression will fail if ); is a string present in any of the columns

To restore it (in a database with the tables already created)

sqlite3 -bail database.db3 < /tmp/backup.sql
星星的轨迹 2024-07-11 03:55:55

最好的方法是采用 sqlite3 数据库转储将执行的代码,不包括架构部分。

伪代码示例:

SELECT 'INSERT INTO ' || tableName || ' VALUES( ' || 
  {for each value} ' quote(' || value || ')'     (+ commas until final)
|| ')' FROM 'tableName' ORDER BY rowid DESC

请参阅:src/shell.c:838(对于 sqlite-3.5.9)了解实际代码

您甚至可以直接使用该 shell 并注释掉模式部分并使用它。

The best method would be to take the code the sqlite3 db dump would do, excluding schema parts.

Example pseudo code:

SELECT 'INSERT INTO ' || tableName || ' VALUES( ' || 
  {for each value} ' quote(' || value || ')'     (+ commas until final)
|| ')' FROM 'tableName' ORDER BY rowid DESC

See: src/shell.c:838 (for sqlite-3.5.9) for actual code

You might even just take that shell and comment out the schema parts and use that.

云淡风轻 2024-07-11 03:55:55

此版本适用于插入中的换行符:

sqlite3 database.sqlite3 .dump | grep -v '^CREATE'

实际上排除所有以 CREATE 开头的行,这些行不太可能包含换行符

This version works well with newlines inside inserts:

sqlite3 database.sqlite3 .dump | grep -v '^CREATE'

In practice excludes all the lines starting with CREATE which is less likely to contain newlines

三月梨花 2024-07-11 03:55:55

retracile 的答案应该是最接近的答案,但它不适用于我的情况。 一个插入查询在中间中断,导出就停止了。 不知道是什么原因。 但是,它在 .dump 期间工作正常。

最后,我编写了一个工具来拆分从 .dump 生成的 SQL:

https:// /github.com/motherapp/sqlite_sql_parser/

The answer by retracile should be the closest one, yet it does not work for my case. One insert query just broke in the middle and the export just stopped. Not sure what is the reason. However It works fine during .dump.

Finally I wrote a tool for the split up the SQL generated from .dump:

https://github.com/motherapp/sqlite_sql_parser/

她说她爱他 2024-07-11 03:55:55

您可以对表进行选择,在每个字段后插入逗号以生成 csv,或者使用 GUI 工具返回所有数据并将其保存到 csv。

You could do a select on the tables inserting commas after each field to produce a csv, or use a GUI tool to return all the data and save it to a csv.

旧夏天 2024-07-11 03:55:55

根据 Command Line Shell For SQLite 的 SQLite 文档,您可以导出 SQLite 表(或部分表格)作为 CSV,只需将“模式”设置为“csv”,然后运行查询来提取表格中所需的行:

sqlite> .header on
sqlite> .mode csv
sqlite> .once c:/work/dataout.csv
sqlite> SELECT * FROM tab1;
sqlite> .exit

然后使用“.import”命令将 CSV(逗号分隔值)数据导入到SQLite 表:

sqlite> .mode csv
sqlite> .import C:/work/dataout.csv tab1
sqlite> .exit

请阅读有关要考虑的两种情况的进一步文档:(1) 表“tab1”以前不存在,(2) 表“tab1”已经存在。

According to the SQLite documentation for the Command Line Shell For SQLite you can export an SQLite table (or part of a table) as CSV, simply by setting the "mode" to "csv" and then run a query to extract the desired rows of the table:

sqlite> .header on
sqlite> .mode csv
sqlite> .once c:/work/dataout.csv
sqlite> SELECT * FROM tab1;
sqlite> .exit

Then use the ".import" command to import CSV (comma separated value) data into an SQLite table:

sqlite> .mode csv
sqlite> .import C:/work/dataout.csv tab1
sqlite> .exit

Please read the further documentation about the two cases to consider: (1) Table "tab1" does not previously exist and (2) table "tab1" does already exist.

木森分化 2024-07-11 03:55:55

例如,您可以使用如下所示的 .dumpapple.db 的架构和数据导出到 backup.sql。 *如果不存在,则创建backup.sql并且我的回答解释了如何将backup.sql导入orange.db

sqlite3 apple.db .dump > backup.sql

并且,您只能导出<的架构code>apple.db 到 backup.sql with .schema 如下所示:

sqlite3 apple.db .schema > backup.sql

此外,您还可以导出 apple.db 的 schema 和数据使用以下命令将 复制到 backup.sql。 *.output 根据文件存在情况创建并选择或仅选择一个文件,并且您必须退出才能关闭该文件(例如,.exit.quit< /code>) 否则 SQLite 命令的结果将输出到文件中:

sqlite3 apple.db
sqlite> .output backup.sql
sqlite> .dump
sqlite> .exit

并且,您可以将 apple.db 中特定表的架构和数据导出到 backup.sql 使用以下命令:

sqlite3 apple.db
sqlite> .output backup.sql
sqlite> .dump person animal
sqlite> .exit

并且,您可以使用以下命令仅将 apple.db 的架构导出到 backup.sql

sqlite3 apple.db
sqlite> .output backup.sql
sqlite> .schema
sqlite> .exit

并且,您可以仅导出使用以下命令将 apple.db 中的特定表复制到 backup.sql。 *.schema 仅导出一个特定表的架构,因此如果您想导出特定多个表的架构,则应多次运行 .schema

sqlite3 apple.db
sqlite> .output backup.sql
sqlite> .schema person
sqlite> .schema animal
sqlite> .exit

最后,您可以使用以下命令仅将 apple.db 中特定表的数据导出到 backup.sql

sqlite3 apple.db
sqlite> .mode insert
sqlite> .output backup.sql
sqlite> SELECT * FROM person, animal;
sqlite> .exit

For example, you can export the schema and data of apple.db to backup.sql with .dump shown below. *backup.sql is created if it doesn't exist and my answer explains how to import backup.sql into orange.db:

sqlite3 apple.db .dump > backup.sql

And, you can export only the schema of apple.db to backup.sql with .schema as shown below:

sqlite3 apple.db .schema > backup.sql

Moreover, you can export the schema and data of apple.db to backup.sql with the commands below. *.output creates and selects or only selects a file depending on the file existence and you must exit to close the file (e.g., .exit or .quit) otherwise the results of SQLite commands are output to the file:

sqlite3 apple.db
sqlite> .output backup.sql
sqlite> .dump
sqlite> .exit

And, you can export the schema and data of the specific tables in apple.db to backup.sql with the commands below:

sqlite3 apple.db
sqlite> .output backup.sql
sqlite> .dump person animal
sqlite> .exit

And, you can export only the schema of apple.db to backup.sql with the commands below:

sqlite3 apple.db
sqlite> .output backup.sql
sqlite> .schema
sqlite> .exit

And, you can export only the schema of the specific tables in apple.db to backup.sql with the commands below. *.schema exports the schema of only one specific table so you should run .schema multiple times if you want to export the schema of the specific multiple tables:

sqlite3 apple.db
sqlite> .output backup.sql
sqlite> .schema person
sqlite> .schema animal
sqlite> .exit

Lastly, you can export only the data of the specific tables in apple.db to backup.sql with the commands below:

sqlite3 apple.db
sqlite> .mode insert
sqlite> .output backup.sql
sqlite> SELECT * FROM person, animal;
sqlite> .exit
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文