如何将ASCII(ISO / IEC 8859-1)中的数据导入到我的Rails / PGSQL数据库?

时间:2014-07-16 23:41:37

标签: mysql ruby-on-rails postgresql ruby-on-rails-4 import

我正在尝试使用此处的USDA数据:http://www.ars.usda.gov/Services/docs.htm?docid=23634

  

ASCII(8.6Mb) - 此文件包含ASCII(ISO / IEC 8859-1)中的SR26数据,分隔文件。这些表以关系格式组织,最好与关系数据库管理系统(RDBMS)一起使用,这将允许您形成自己的数据库查询并生成自定义报告。

我是新手操纵这样的数据并且想我想用CSV格式,也许吧?但是,那么我可能会失去关系,所以也许我应该去PGSQL。不知道如何处理这个问题。

寻求指导,谢谢。

3 个答案:

答案 0 :(得分:27)

该zip包含许多文件:

  inflating: DATA_SRC.txt            
  inflating: DATSRCLN.txt            
  inflating: DERIV_CD.txt            
  inflating: FD_GROUP.txt            
  inflating: FOOD_DES.txt            
  inflating: FOOTNOTE.txt            
  inflating: LANGDESC.txt            
  inflating: LANGUAL.txt             
  inflating: NUT_DATA.txt            
  inflating: NUTR_DEF.txt            
  inflating: sr26_doc.pdf            
  inflating: SRC_CD.txt              
  inflating: WEIGHT.txt         

每个似乎都是奇怪的几乎类似CSV的格式,例如NUTR_DEF.txt

~287~^~g~^~GALS~^~Galactose~^~2~^~2100~
~291~^~g~^~FIBTG~^~Fiber, total dietary~^~1~^~1200~

sr26_doc.pdf,文档。

创建表定义

所以你需要做的是为数据库创建SQL表定义 - 每个输入文件都有一个表。你需要CREATE TABLE命令;请参阅PostgreSQL文档。

PDF的第35页应该对您有所帮助 - “图1.美国农业部国家营养数据库中标准参考文件之间的关系”。以下页面描述了文件格式,告诉您每列的含义。您可以根据此说明编写CREATE TABLE语句。

这是一个例子,对于FOOD_DES.txt(食物描述),第一个条目。

CREATE TABLE food_des (
    "NDB_No"      varchar(5) NOT NULL PRIMARY KEY,
    "FdGrp_Cd"    varchar(4) NOT NULL,
    "Long_Desc"   varchar(200) NOT NULL,
    "Shrt_Desc"   varchar(60) NOT NULL,
    "ComName"     varchar(100),
    "ManufacName" varchar(65),
    "Survey"      varchar(1),
    "Ref_desc"    varchar(135),
    "Refuse"      smallint,
    "SciName"     varchar(65),
    "N_Factor"    NUMERIC(4,2),
    "Pro_Factor"  NUMERIC(4,2),
    "Fat_Factor"  NUMERIC(4,2),
    "CHO_Factor"  NUMERIC(4,2)
);

这是该描述的文字副本。这不是我设计表格的方式

我在非整数数字类型中使用NUMERIC任意精度十进制浮点类型来提高准确性。如果效果比准确性更重要,则可以改为使用float4

对于关系,您使用FOREIGN KEY个约束 - 只需colname coltype REFERENCES othertable(othercol)即可创建一个约束。

重要:我双引号列名称以保留与定义中相同的名称。这意味着当你引用它们时,你必须总是双引号,例如SELECT "NDB_No" FROM food_des;。如果您不想这样,只需不要使用双引号 - 或选择不同的名称。你不必坚持他们使用的笨拙的缩写列名,写起来是合理的:

CREATE TABLE food_description (
    ndb_no              varchar(5) NOT NULL PRIMARY KEY,
    foodgroup_code      varchar(4) NOT NULL,
    long_description    varchar(200) NOT NULL,
    short_description   varchar(60) NOT NULL,
    common_name         varchar(100),
    manufacturer_name   varchar(65),

等。类似地,如果你正在使用Rails,你可以转换表定义以遵循Rails的约定,特别是如果你打算通过Rails进行数据加载。

正在加载数据

如果这些是理智的,明智的分隔文件,那么您可以使用psql命令\copy或PgAdmin-III的“导入”选项加载每个表。

它实际上是CSV,他们刚刚决定使用完全奇怪的分隔符和引用字符。通过psql导入:

\copy food_des FROM 'FOOD_DES.txt' (FORMAT CSV, DELIMITER '^', QUOTE '~');

或用于与PostgreSQL交谈的任何工具中的等效文件。

结果是一个明智的表格:

craig=> select * from food_des limit 2;
 NDB_No | FdGrp_Cd |         Long_Desc          |        Shrt_Desc         | ComName | ManufacName | Survey | Ref_desc | Refuse | SciName | N_Factor | Pro_Factor | Fat_Factor | CHO_Factor 
--------+----------+----------------------------+--------------------------+---------+-------------+--------+----------+--------+---------+----------+------------+------------+------------
 01001  | 0100     | Butter, salted             | BUTTER,WITH SALT         |         |             | Y      |          |      0 |         |     6.38 |       4.27 |       8.79 |       3.87
 01002  | 0100     | Butter, whipped, with salt | BUTTER,WHIPPED,WITH SALT |         |             | Y      |          |      0 |         |     6.38 |       4.27 |       8.79 |       3.87
(2 rows)

同样,如果使用Rails,您可以使用您想要的任何Rails CSV库并批量加载到模型中。

答案 1 :(得分:1)

使用@ craig-ringer的提示,我创建了一个脚本,将原来的USDA Nutrition数据库文件迁移到postgreSQL。

目前是否非常粗糙,但应该有助于开始。

在这里查看: https://github.com/rlucha/usda-nutrition-database-migration

答案 2 :(得分:0)

他们有一个用于Microsoft访问的数据库版本,如果你有,你可以下载访问然后使用StatusBar转换为MySQL。