解析csv文件以填充数据库

时间:2016-08-23 13:50:16

标签: java amazon-web-services amazon-dynamodb aws-lambda

鉴于我有一个像这样的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还是字符串。

2 个答案:

答案 0 :(得分:0)

只需存储标签(第一行),然后在迭代行值时,根据标签决定调用哪种方法。如果你不反对带来一些外部依赖,我建议你使用一些外部的csv阅读器,例如 SuperCsv 使用此库,您可以将每行读取为Map(label-> val),然后迭代条目并根据标签使用正确的方法更新db。或者只是读取标题,然后将每行作为列表进行相同的读取。

示例:

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

.chatbrd
{
height:800px;
position:relative;
overflow:auto;
max-height:200px;
border:1px solid black
}

.newmsg
{
 position:absolute;
 bottom:0;
  max-width:600px;  

 }
.newmsg textarea
{
width:100%;

}

答案 1 :(得分:0)

好的,我不能将此作为评论发布,所以我写了一个简单的例子。请注意,我不熟悉您正在使用的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();
}

此示例假定您的第一行包含存储在数据库中的列名。你不必在任何地方写,无论是int还是String,因为程序中有一个检查(认为这不是最有效的方法,你可以写一些更好的东西,也许是Molok所建议的)