【问题标题】:Best way to print out Mnesia table打印出 Mnesia 表的最佳方法
【发布时间】:2011-12-07 12:05:07
【问题描述】:

我试过这段代码sn-p:

print_next(Current) ->
    case mnesia:dirty_next(muppet, Current) of
        '$end_of_table' ->
            io:format("~n", []),
            ok;
        Next ->
            [Muppet] = mnesia:dirty_read({muppet, Next}),
            io:format("~p~n", [Muppet]),
            print_next(Next),
            ok
    end.

print() ->
    case mnesia:dirty_first(muppet) of
        '$end_of_table' ->
            ok;
        First ->
            [Muppet] = mnesia:dirty_read({muppet, First}),
            io:format("~p~n", [Muppet]),
            print_next(First),
            ok
    end.

但它是如此之长。我也可以使用dirty_all_keys,然后遍历键列表,但我想知道是否有更好的方法来打印出 Mnesia 表内容。

【问题讨论】:

  • 如果您只是在寻找一种浏览表格的方式,您也可以使用table visualizer

标签: erlang mnesia


【解决方案1】:

好吧,如果要查看表的内容,则有一个名为 tv 的应用程序,它可以查看 ETS 和 mnesia 表。

如果您希望在终端上查看所有表格内容,请尝试以下操作:

traverse_table_and_show(Table_name)-> 迭代器 = fun(Rec,_)-> io:format("~p~n",[Rec]), [] 结尾, 案例记忆:is_transaction() 的 true -> mnesia:foldl(Iterator,[],Table_name); 假-> Exec = fun({Fun,Tab}) -> mnesia:foldl(Fun, [],Tab) end, mnesia:activity(transaction,Exec,[{Iterator,Table_name}],mnesia_frag) 结尾。

那么如果你的表叫muppet,你使用函数如下:

traverse_table_and_show(布偶)。

这样做的优点:
如果它在一个事务中执行,它不会有嵌套事务的问题。与您的 get_next_key -> do_read_with_key -> 然后读取记录(这些是许多操作)的实现相比,它通过 mnesia 迭代器功能在一个 mnesia 事务中完成,因此工作量更少。有了这个,mnesia 会自动告诉它已经覆盖了整个表中的所有记录。此外,如果表是分段的,您的功能将仅显示第一个分段中的记录。这将遍历属于该表的所有片段。

在这个迭代 mnesia 方法中,我对应该与 Iterator fun 一起使用的 Accumulator 变量不做任何事情,这就是为什么您会看到第二个变量的下划线。

可以在此处找到此迭代的详细信息:<b>@987654322@@987654323@</b>

【讨论】:

    【解决方案2】:

    如果你只是想要一种快速而肮脏的方式在 shell 中打印 Mnesia 表的内容,并且如果你的表不是disc_only_copies 类型,那么你可以利用 Mnesia 将其数据存储在ETS 表和运行:

    ets:tab2list(my_table).
    

    或者,如果您认为 shell 过多地截断数据:

    rp(ets:tab2list(my_table)).
    

    当然,不推荐用于“真实”代码。

    【讨论】:

    • 如果数据太多,该列表可能会占用 shell 进程。在执行此操作之前请注意 ETS 表中的数据大小
    【解决方案3】:

    正如 Muzaaya 所说,您可以使用 tv(表格可视化工具)来查看 mnesia 和 ets 表格。 或者,您可以使用以下代码获取 mnesia 表数据 - 在终端上打印或将结果存储在文件中:

    select_all() -> 
       mnesia:transaction( 
    fun() ->
        P=qlc:e(qlc:q([E || E <- mnesia:table(tableName)])),      %query to select all data from table named 'tableName'                                                                                    
        io:format(" ~p ~n ", [P]), % Prints table data on terminal
        to_file("fileName.txt",P) % to_file method writes the data to file
    end ).
    
    
    to_file(File, L) ->
      mnesia:transaction( 
    fun() ->
          {ok, S} = file:open(File, write),
          lists:foreach(fun(X) -> io:format(S, "~p.~n" ,[X]) end, L),
          file:close(S)
      end).
    

    【讨论】:

      【解决方案4】:

      为了简单快速地查看表格内容,您可以使用 mnesiaselect 函数和 catch-all Match Specification,如下所示:

      CatchAll = [{'_',[],['$_']}].
      mnesia:dirty_select(TableName, CatchAll).
      

      您也可以在事务上下文中运行它:

      CatchAll = [{'_',[],['$_']}].
      SelectFun = fun() -> mnesia:select(TableName, CatchAll) end.
      mnesia:transaction(SelectFun).
      

      但是,如果您在具有大数据的生产环境中,请小心。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-08-03
        • 2012-02-09
        • 2011-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-26
        相关资源
        最近更新 更多