将csv文件中的数据注册到mnesia数据库
我想将csv文件中的数据存储在mnesia数据库中(特别是在名为“user”的表中) 我在这个论坛上发现了这种解决方案: 创建名为csv.erl的外商投资企业:将csv文件中的数据注册到mnesia数据库,csv,erlang,Csv,Erlang,我想将csv文件中的数据存储在mnesia数据库中(特别是在名为“user”的表中) 我在这个论坛上发现了这种解决方案: 创建名为csv.erl的外商投资企业: %%% --- csv parser in Erlang. ------ %%% To help process large csv files without loading them into %%% memory. Similar to the xml parsing technique of SAX -module(csv).
%%% --- csv parser in Erlang. ------
%%% To help process large csv files without loading them into
%%% memory. Similar to the xml parsing technique of SAX
-module(csv).
-compile(export_all).
parse(FilePath,ForEachLine,Opaque)->
case file:open(FilePath,[read]) of
{_,S} ->
start_parsing(S,ForEachLine,Opaque);
Error -> Error
end.
start_parsing(S,ForEachLine,Opaque)->
Line = io:get_line(S,''),
case Line of
eof -> {ok,Opaque};
"\n" -> start_parsing(S,ForEachLine,Opaque);
"\r\n" -> start_parsing(S,ForEachLine,Opaque);
_ ->
NewOpaque = ForEachLine(scanner(clean(clean(Line,10),13)),Opaque),
start_parsing(S,ForEachLine,NewOpaque)
end.
scan(InitString,Char,[Head|Buffer]) when Head == Char ->
{lists:reverse(InitString),Buffer};
scan(InitString,Char,[Head|Buffer]) when Head =/= Char ->
scan([Head|InitString],Char,Buffer);
scan(X,_,Buffer) when Buffer == [] -> {done,lists:reverse(X)}.
scanner(Text)-> lists:reverse(traverse_text(Text,[])).
traverse_text(Text,Buff)->
case scan("",$,,Text) of
{done,SomeText}-> [SomeText|Buff];
{Value,Rem}-> traverse_text(Rem,[Value|Buff])
end.
clean(Text,Char)->
string:strip(string:strip(Text,right,Char),left,Char).
创建函数测试:
test()->
ForEachLine = fun(Line,Buffer)-> io:format("Line: ~p~n",[Line]),Buffer end,
InitialBuffer = [],
csv:parse("/home/include/user.csv",ForEachLine,InitialBuffer).
但是这个解决方案只显示Erlang控制台中的数据(它显示csv文件中的每一行),但我的目标是将csv文件中的这些行存储在用户表中
我已经创建了用户的记录
-record(user, {id, firstname, lastname, birthday}).
要将csv文件中的行注册到用户表中,我尝试使用
test()->
ForEachLine = fun(Line,Buffer)-> io:format("Line: ~p~n",[Line]),Buffer end,
InitialBuffer = [],
csv:parse("/home/test/user.csv",ForEachLine,InitialBuffer),
F = fun() ->
Line=#user{},
mnesia:write(Line),
{ok}
end,
{atomic, Val} = mnesia:transaction(F),
Val.
但此函数不在用户表中插入数据您需要做几件事:
- 在mnesia中创建一个模式,它将保存您的数据。即创建一个
记录#user{}
- 将您的行放入
R=#user{}
- 调用
。为了加快速度,您可以在同一事务中批处理几次写入,或者只需使用mnesia:在事务内部写入(R)
mnesia:dirty\u write(R)
缓冲区现在只是一个计数器。这将自动显示从.csv
文件插入mnesia的记录总数
请记住erlang数据结构的通用性。您的乐趣
,只要它被构造为包含两个变量,第一个变量是行,您就可以将其自定义为任何变量。在Fun
中,您甚至可以将行
发送到另一个erlang节点或erlang进程。像这样:
F = fun(Line,Server)->
[Id,Firstname, Lastname, Birthday] = Line,
U = #user{
id = Id,
firstname = Firstname,
lastname = Lastname,
birthday = Birthday
},
Server ! {from_csv,U}
Server
end.
请更改上述函数以反映您的分隔符。例如,如果分隔符是分号(;)
,则该函数将更改为:
traverse_text(Text,Buff)->
case scan("",$;,Text) of
{done,SomeText}-> [SomeText|Buff];
{Value,Rem}-> traverse_text(Rem,[Value|Buff])
end.
遍历文本(文本,浅黄色)->
大小写扫描(“,$;文本)
{done,SomeText}->[SomeText|Buff];
{Value,Rem}->遍历文本(Rem,[Value}Buff])
结束。
因此,如果您的定界符
不同,只需对该函数进行更改,如我上面所示(我希望您看到符号的位置,看到的是美元符号,后面是实际的定界符
)。然后,重新编译并重新加载该模块。如果遇到更多挑战,请告诉我。分隔符可能会在不同的.csv
文件中更改。查看答案编辑,了解如何自定义.csv解析器
,以适应任何分隔符
。在解析器中,我假设了一个逗号
。
traverse_text(Text,Buff)->
case scan("",$,,Text) of
{done,SomeText}-> [SomeText|Buff];
{Value,Rem}-> traverse_text(Rem,[Value|Buff])
end.
traverse_text(Text,Buff)->
case scan("",$;,Text) of
{done,SomeText}-> [SomeText|Buff];
{Value,Rem}-> traverse_text(Rem,[Value|Buff])
end.