【问题标题】:How to import csv file to sqlite with correct data types如何使用正确的数据类型将 csv 文件导入到 sqlite
【发布时间】:2013-12-12 23:13:34
【问题描述】:

当我将 csv 文件导入 sqlite 数据库时,它会将数字作为字符串导入整数列,我该如何解决这个问题?我的 csv 文件中的一行是这样的:

 31,c,BB ROSE - 031,c31,,9,7,0,"142,000",0

【问题讨论】:

  • 请包含您的表的架构。

标签: sqlite csv types import


【解决方案1】:

CSV 文件没有数据类型;一切都是字符串。

要将列中的所有值转换为数字,请使用以下内容:

UPDATE MyTable SET MyColumn = CAST(MyColumn AS INTEGER)

【讨论】:

  • 这不起作用。您不能在 SQLite 中修改这样的列。该列未更改。
  • @Spacedman 您很可能导入了一个表,其中该列使用文本 affinity 声明。
  • 我没有导入到任何现有表中 - 如果将 CSV 导入到新表中,则会得到文本表,这就是问题所在。解决方法是首先创建表 - 然后您将使用正确的类型来完成它,并且无论如何都不需要执行任何更新。
【解决方案2】:

在 SQLite 中,您无法更改列的类型关联。因此,您应该 create 您的表,然后将 .import 您的 CSV 文件放入表中。如果您的 CSV 文件有标题,则在导入时将被视为数据。您可以在导入前删除标题(在 CSV 文件中),也可以在导入后删除标题(在表格中)。由于typeof 所有的标题字段都将是TEXT,因此您可以在某些列具有数字类型相关性的表中轻松找到此标题。

【讨论】:

  • 请解释您的反对意见。你确定你明白为什么提出这个而不是CAST吗?
  • 如果您对如何执行此操作感兴趣:看看您是否会删除正确的东西(安全第一)SELECT * FROM MyTable WHERE MyColumn = 'HeaderName',然后删除DELETE FROM MyTable WHERE MyColumn = 'HeaderName'
【解决方案3】:

导入 csv 文件时,SQLite 假定所有字段都是文本字段。因此,您需要执行一些额外的步骤才能设置正确的数据类型。

但是,据我了解,您不能使用ALTER TABLE 语句来修改 SQLite 中的列。 相反,您需要重命名表、创建新表并将数据复制到新表中。

https://www.techonthenet.com/sqlite/tables/alter_table.php

假设我有一个 employees.csv 文件,我想用正确的数据类型导入 SQLite 数据库。

employee_id,last_name,first_name,hire_date
1001,adams,john,2010-12-12
1234,griffin,meg,2000-01-01
2233,simpson,bart,1990-02-23

首先,创建一个名为mydb.sqlite 的SQLite 数据库,并将employees.csv 导入一个名为employees 的SQLite 表中。

# create sqlite database called mydb.sqlite
# import data from 'employees.csv' into a SQLite table called 'employees'
# unfortunately, sqlite assumes all fields are text fields

$ sqlite3 mydb.sqlite
sqlite> .mode csv
sqlite> .import employees.csv employees
sqlite> .quit

此时,数据以文本形式导入。让我们首先从数据库中获取employees 架构并将其保存到employees.sql。我们可以使用它来创建一个新脚本,该脚本将重命名表,创建一个新表,并将数据复制到新表中。

$ sqlite3 mydb.sqlite
sqlite> .once employees.sql
sqlite> .schema employees
sqlite> .quit

您现在应该拥有具有以下架构的 employees.sql

CREATE TABLE employees(
  "employee_id" TEXT,
  "last_name" TEXT,
  "first_name" TEXT,
  "hire_date" TEXT
);

现在让我们创建一个名为 alterTable.sql 的 SQL 文件,该文件将重命名表、创建新表并将数据复制到新表中。

alterTable.sql

PRAGMA foreign_keys=off;

BEGIN TRANSACTION;

ALTER TABLE employees RENAME TO _employees_old;


CREATE TABLE employees
( "employee_id" INTEGER,
  "last_name" TEXT,
  "first_name" TEXT,
  "hire_date" NUMERIC
);

INSERT INTO employees ("employee_id", "last_name", "first_name", "hire_date")
  SELECT "employee_id", "last_name", "first_name", "hire_date"
  FROM _employees_old;

COMMIT;

PRAGMA foreign_keys=on;

最后,我们可以在alterTable.sql中执行SQL并删除旧的重命名表

$ sqlite3 mydb.sqlite
sqlite> .read alterTable.sql
sqlite> drop table _employees_old;

此时,导入的员工数据应该具有正确的数据类型,而不是默认的文本字段。

如果您这样做,您不必担心 csv 文件中的标头会被导入为数据。其他方法可能需要您在导入 csv 文件之前或之后删除标题。

【讨论】:

  • 虽然已经回答了这个问题,但我感谢您为我的用例编写的内容。
【解决方案4】:

您只需要先创建具有正确类型的表,然后 CSV 导入将保留此类型,因为该表已经存在。

这里是一个示例:

create table table1(name TEXT, wert INT);
.mode csv
.separator ";"
.import "d:/temp/test.csv" table1

如果您需要删除导入的标题行,请在导入后使用类似这样的内容:

delete from table1 where rowid=1;

如果您已经对同一个表进行了多次导入,请使用它:

delete from [table1] where "name"='name'; -- try to use a name of an INT-column for this.

最后你可以像这样检查正确的导入:

.header ON
select * from table1 order by wert;

【讨论】:

    【解决方案5】:
    1. 将 CSV 文件导入 SQLite。
    2. 转到数据库结构并选择导入的 CSV 文件
    3. 从选项卡中选择修改表
    4. 选择字段一并将名称更改为所需的列名称。
    5. 接下来从下拉菜单中选择所需的数据类型。您现在可以根据您使用的数据从文本更改为整数或数字

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-03-05
      • 2018-09-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-15
      • 2012-08-05
      • 2018-10-29
      相关资源
      最近更新 更多