解析csv文件以填充数据库



假设我有一个像这样的csv文件

str_name,int_points,int_bonus
joe,2,5
Moe,10,15
Carlos,25,60

我可以有x列数和y行数的csv文件,所以我试图开发一种通用的方法来解析它,并在dynamodb表中填充数据。

为了填充dynamodb表,我将做如下操作

String line = "";
    String cvsSplitBy = ",";
    try (BufferedReader br = new BufferedReader(
                                new InputStreamReader(objectData, "UTF-8"));
        while ((line = br.readLine()) != null) {
            // use comma as separator
            String[] elements = line.split(cvsSplitBy);
            try {
                table.putItem(new Item()
                    .withPrimaryKey("name", elements[0])
                    .withInt("points", elements[1])
                    .withInt("bonus", elements[2])
                    .....);
                System.out.println("PutItem succeeded: " + elements[0]);
            } catch (Exception e) {
                System.err.println("Unable to add user: " + elements);
                System.err.println(e.getMessage());
                break;
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
    }

然而,我并不总是知道我是否插入一个int或字符串,它是依赖于csv文件,所以我有点失去了如何创建一个通用函数,它将读取我的csv文件的第一行,并利用前缀,这表明如果特定列是一个int或字符串。

只需存储标签(第一行),然后在遍历行值时,根据标签决定调用哪个方法。如果你不反对引入一些外部依赖,我建议你使用一些外部csv阅读器,例如。SuperCsv例如,使用这个库,您可以将每一行读取为Map(label->val),然后遍历条目并基于标签前缀使用正确的方法更新数据库。或者只读取header,然后像读取列表一样读取每一行。

的例子:

这当然是非常粗糙的,我可能会以某种方式重构它(例如,为每列提供一个处理器列表,而不是丑陋的开关)但是它向你展示了这个想法

        List<String> labels = new ArrayList<>();//store first row here
        List<String> elements = new ArrayList<>();//currently processed line here
        Item item = new Item();
        for (int i = 0; i < elements.size(); i++) {
            String label = labels.get(i);
            switch (getTypePrefix(label)){
                case "int":
                    item = item.withInt(getName(label),elements.get(i));
                    break;
                case "str":
                    item = item.withString(getName(label),elements.get(i));
                    break;
                default:
                    //sth
                    break;
            }
        }
        table.putItem(item);

好吧,我不能把这个作为评论,所以我写了一个简单的例子。注意,我不熟悉你使用的Amazon API但你应该知道我是怎么做的(我基本上重写了你的代码)

        String line = "";
        String cvsSplitBy = ",";
        try (BufferedReader br = new BufferedReader(
                            new InputStreamReader(objectData, "UTF-8"));
     String[]  colNames = br.readLine().split(cvsSplitBy);      //first line just to get the column names
     while ((line = br.readLine()) != null) {
        String currColumnName = colNames.get(i);
        // use comma as separator
        String[] elements = line.split(cvsSplitBy);
        boolean isInt ;
        for (int i = 0; i < elements.length;i++){
        try {
            try{
            int iVal = new Integer(elements[i]);
            isInt = true;
            }catch(NumberFormatException e){
            //process exception
            isInt = false;
            }
            if(isInt){
            table.putItem.(new Item().withInt(currColumnName,iVal));
            }else{
            table.putItem.(new Item().withString(currColumnName),elements[i])); //don't even know whether there is a withString method
            }
            System.out.println("PutItem succeeded: " + elements[i]);
        } catch (Exception e) {
            System.err.println("Unable to add user: " + elements);
            System.err.println(e.getMessage());
            break;
        }
        }
    }
} catch (IOException e) {
    e.printStackTrace();
}

本例假设第一行包含存储在DB中的列名。你不必在任何地方写它们是int还是String,因为程序中有一个检查(假设这不是最有效的方法,你可以写一些更好的东西,也许是Molok建议的)

相关内容

  • 没有找到相关文章

最新更新