mnesia:transform_table

classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

mnesia:transform_table

andrew mmc
Hello,

I needed to change the structure of an mnesia table.  I followed the example
in the documentation:

-record(old, {key, val}).
-record(new, {key, val, extra}).

Transformer =
   fun(X) when record(X, old) ->
      #new{key = X#old.key,
           val = X#old.val,
           extra = 42}
   end,
{atomic, ok} = mnesia:transform_table(foo, Transformer,
                                      record_info(fields, new),
                                      new)

Substituting the record names and field mappings as per my
requirement. The transformation function works fine when I test it on
a record of the old type, outputting the new record ok.

However, now when I try to read from the new table, mnesia reports
no_exists, and the old table still exists but reads as empty...  Where
has my data gone?!

Any help much appreciated!

Regards,


Andrew
Reply | Threaded
Open this post in threaded view
|

Re: mnesia:transform_table

Håkan Mattsson
It looks like you have done the right thing. Perhaps you have
simplified your code too much in order to post it on the list?

I tried to reproduce your error, but it worked for me.
See the printouts and the test program below.

/Håkan

16> foo:go(foo).
Before: [{old,7,49},
         {old,6,36},
         {old,4,16},
         {old,1,1},
         {old,9,81},
         {old,10,100},
         {old,8,64},
         {old,2,4},
         {old,3,9},
         {old,5,25}]
Before: [{new,7,49,42},
         {new,6,36,42},
         {new,4,16,42},
         {new,1,1,42},
         {new,9,81,42},
         {new,10,100,42},
         {new,8,64,42},
         {new,2,4,42},
         {new,3,9,42},
         {new,5,25,42}]
ok


-module(foo).
-compile([export_all]).

-record(old, {key, val}).
-record(new, {key, val, extra}).

go(Tab) ->
    mnesia:delete_table(Tab),
    {atomic, ok} = mnesia:create_table(Tab, [{attributes,
record_info(fields, old)},
                                             {record_name, old}]),
    [mnesia:dirty_write(Tab, #old{key = K, val = K*K}) || K <- lists:seq(1,10)],
    io:format("Before: ~p\n", [ets:tab2list(Tab)]),
    Transformer =
        fun(#old{key = Key, val = Val}) ->
                #new{key = Key, val = Val, extra = 42}
        end,
    {atomic, ok} = mnesia:transform_table(Tab, Transformer,
                                          record_info(fields, new),
                                          new),
    io:format("Before: ~p\n", [ets:tab2list(Tab)]).



On Wed, Nov 25, 2009 at 2:07 PM, andrew mmc <[hidden email]> wrote:

> Hello,
>
> I needed to change the structure of an mnesia table.  I followed the example
> in the documentation:
>
> -record(old, {key, val}).
> -record(new, {key, val, extra}).
>
> Transformer =
>   fun(X) when record(X, old) ->
>      #new{key = X#old.key,
>           val = X#old.val,
>           extra = 42}
>   end,
> {atomic, ok} = mnesia:transform_table(foo, Transformer,
>                                      record_info(fields, new),
>                                      new)
>
> Substituting the record names and field mappings as per my
> requirement. The transformation function works fine when I test it on
> a record of the old type, outputting the new record ok.
>
> However, now when I try to read from the new table, mnesia reports
> no_exists, and the old table still exists but reads as empty...  Where
> has my data gone?!
>
> Any help much appreciated!
>
> Regards,
>
>
> Andrew

On Wed, Nov 25, 2009 at 2:07 PM, andrew mmc <[hidden email]> wrote:

> Hello,
>
> I needed to change the structure of an mnesia table.  I followed the example
> in the documentation:
>
> -record(old, {key, val}).
> -record(new, {key, val, extra}).
>
> Transformer =
>   fun(X) when record(X, old) ->
>      #new{key = X#old.key,
>           val = X#old.val,
>           extra = 42}
>   end,
> {atomic, ok} = mnesia:transform_table(foo, Transformer,
>                                      record_info(fields, new),
>                                      new)
>
> Substituting the record names and field mappings as per my
> requirement. The transformation function works fine when I test it on
> a record of the old type, outputting the new record ok.
>
> However, now when I try to read from the new table, mnesia reports
> no_exists, and the old table still exists but reads as empty...  Where
> has my data gone?!
>
> Any help much appreciated!
>
> Regards,
>
>
> Andrew

________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org

Reply | Threaded
Open this post in threaded view
|

Re: mnesia:transform_table

andrew mmc
Hi Håkan,

Thanks for your answer... Actually I see that it has worked - I expected the
table name to change with the record name, but the name is the same as
before.  I got an empty table because I used dirty_match_object without
specifying the 'old' table name.

So I guess the next question, is: how do I change the table name!?

Thanks,

Andrew

2009/11/25 Håkan Mattsson <[hidden email]>

> It looks like you have done the right thing. Perhaps you have
> simplified your code too much in order to post it on the list?
>
> I tried to reproduce your error, but it worked for me.
> See the printouts and the test program below.
>
> /Håkan
>
> 16> foo:go(foo).
> Before: [{old,7,49},
>         {old,6,36},
>         {old,4,16},
>         {old,1,1},
>         {old,9,81},
>         {old,10,100},
>         {old,8,64},
>         {old,2,4},
>         {old,3,9},
>         {old,5,25}]
> Before: [{new,7,49,42},
>         {new,6,36,42},
>         {new,4,16,42},
>         {new,1,1,42},
>         {new,9,81,42},
>         {new,10,100,42},
>         {new,8,64,42},
>         {new,2,4,42},
>         {new,3,9,42},
>         {new,5,25,42}]
> ok
>
>
> -module(foo).
> -compile([export_all]).
>
> -record(old, {key, val}).
> -record(new, {key, val, extra}).
>
> go(Tab) ->
>    mnesia:delete_table(Tab),
>    {atomic, ok} = mnesia:create_table(Tab, [{attributes,
> record_info(fields, old)},
>                                             {record_name, old}]),
>    [mnesia:dirty_write(Tab, #old{key = K, val = K*K}) || K <-
> lists:seq(1,10)],
>    io:format("Before: ~p\n", [ets:tab2list(Tab)]),
>    Transformer =
>        fun(#old{key = Key, val = Val}) ->
>                #new{key = Key, val = Val, extra = 42}
>        end,
>    {atomic, ok} = mnesia:transform_table(Tab, Transformer,
>                                          record_info(fields, new),
>                                          new),
>    io:format("Before: ~p\n", [ets:tab2list(Tab)]).
>
>
>
> On Wed, Nov 25, 2009 at 2:07 PM, andrew mmc <[hidden email]> wrote:
> > Hello,
> >
> > I needed to change the structure of an mnesia table.  I followed the
> example
> > in the documentation:
> >
> > -record(old, {key, val}).
> > -record(new, {key, val, extra}).
> >
> > Transformer =
> >   fun(X) when record(X, old) ->
> >      #new{key = X#old.key,
> >           val = X#old.val,
> >           extra = 42}
> >   end,
> > {atomic, ok} = mnesia:transform_table(foo, Transformer,
> >                                      record_info(fields, new),
> >                                      new)
> >
> > Substituting the record names and field mappings as per my
> > requirement. The transformation function works fine when I test it on
> > a record of the old type, outputting the new record ok.
> >
> > However, now when I try to read from the new table, mnesia reports
> > no_exists, and the old table still exists but reads as empty...  Where
> > has my data gone?!
> >
> > Any help much appreciated!
> >
> > Regards,
> >
> >
> > Andrew
>
> On Wed, Nov 25, 2009 at 2:07 PM, andrew mmc <[hidden email]> wrote:
> > Hello,
> >
> > I needed to change the structure of an mnesia table.  I followed the
> example
> > in the documentation:
> >
> > -record(old, {key, val}).
> > -record(new, {key, val, extra}).
> >
> > Transformer =
> >   fun(X) when record(X, old) ->
> >      #new{key = X#old.key,
> >           val = X#old.val,
> >           extra = 42}
> >   end,
> > {atomic, ok} = mnesia:transform_table(foo, Transformer,
> >                                      record_info(fields, new),
> >                                      new)
> >
> > Substituting the record names and field mappings as per my
> > requirement. The transformation function works fine when I test it on
> > a record of the old type, outputting the new record ok.
> >
> > However, now when I try to read from the new table, mnesia reports
> > no_exists, and the old table still exists but reads as empty...  Where
> > has my data gone?!
> >
> > Any help much appreciated!
> >
> > Regards,
> >
> >
> > Andrew
>
Reply | Threaded
Open this post in threaded view
|

Re: mnesia:transform_table

Håkan Mattsson-2
2009/11/25 andrew mmc <[hidden email]>:

> So I guess the next question, is: how do I change the table name!?

It is not supported. As a last resort you can do it off-line by creating a
backup, use mnesia:traverse_backup/8 to patch the backup and then
restore the database from the backup. But if you would do that you
could transform the records off-line also.

/Håkan

________________________________________________________________
erlang-questions mailing list. See http://www.erlang.org/faq.html
erlang-questions (at) erlang.org

Reply | Threaded
Open this post in threaded view
|

Re: mnesia:transform_table

andrew mmc
That would be the reason I couldn't find it anywhere in the documentation
then!

I'll just live with the old table name, it seems easier!

Thanks very much,

Andrew

2009/11/25 Håkan Mattsson <[hidden email]>

> 2009/11/25 andrew mmc <[hidden email]>:
>
> > So I guess the next question, is: how do I change the table name!?
>
> It is not supported. As a last resort you can do it off-line by creating a
> backup, use mnesia:traverse_backup/8 to patch the backup and then
> restore the database from the backup. But if you would do that you
> could transform the records off-line also.
>
> /Håkan
>