I have in my database mnesia two table which have this syntax :
-record(person, {firstname, lastname,adress}).
-record(personBackup, {firstname, lastname,adress}).
I want to transfer the data from the table person to the table personBackup
I think that I should create the two tables with this syntax ( I'm agree with your idea)
mnesia:create_table(person,
[{disc_copies, [node()]},
{attributes, record_info(fields, person)}]),
mnesia:create_table(person_backup,
[{disc_copies, [node()]},
{attributes, record_info(fields, person)},
{record_name, person}]),
now I have a function named verify
in this function I will do a test and if the test is verified I should transfert data from person to person_backup and then I should do a reset
this is my function
verify(Form)->
if Form =:= 40 ->
%%here I should transert data from person to person_backup : read all lines from person and write this lines into person_backup
reset();
Form =/= 40 ->
io:format("it is ok")
end.
this is the function reset :
reset() ->
stop(),
destroy(),
create(),
start(),
{ok}.
You don't have to use a separate record definition for each table. mnesia:create_table takes a record_name option, so you could create your tables like this:
mnesia:create_table(person,
[{disc_copies, [node()]},
{attributes, record_info(fields, person)}]),
mnesia:create_table(person_backup,
[{disc_copies, [node()]},
{attributes, record_info(fields, person)},
{record_name, person}]),
The value for record_name defaults to the name of the table, so there's no need to specify it for person. (I changed personBackup to person_backup, as Erlang atoms are usually written without camel case, unlike variables.)
Then you can put the same kind of records in both tables. Read or select from person, and write to person_backup, no conversion necessary.
There is no need for a seperated record definition for each table. Variables 90 and 80 will do the trick. If you wish to take a option of recod_name, you could use mnesia:create_table
# legoscia, you are correct for everything except for line 6.
mnesia:create_table(person, if player value = 1
this way the outcome can disc all copies and nodes.
Related
So I'm getting {aborted,{bad_type,link,disc_copies, 'my_server#127.0.0.1'}} (it is returned by my init_db/0 function):
-record(link, {hash, original, timestamp}).
init_db() ->
application:set_env(mnesia, dir, "/tmp/mnesia_db"),
mnesia:create_schema([node()]),
mnesia:start(),
mnesia:create_table( link,[
{index,[timestamp]},
{attributes, record_info(fields, link)},
{disc_copies, [node()]}]).
Without {disc_copies, [node()]} table is properly created.
Verify write permissions on the parent directory of the mnesia dir you're specifying via application:set_env/3. If the mnesia dir parent directory doesn't allow you to write, you'll get this error. (Another way to get this error is to forget to set mnesia dir entirely, but your set_env call is clearly doing that.)
Update: looking more carefully at your reported error, I see the node mentioned in the error is not in a list:
{aborted,{bad_type,link,disc_copies, 'my_server#127.0.0.1'}}
This might mean that the code you show in your question doesn't match what's really running. Specifically, if you call mnesia:create_table/2 passing a node instead of a list of nodes in the disc_copies tuple, as shown below, you'll get the same exact error:
mnesia:create_table(link,[{index,[timestamp]},
{attributes, record_info(fields, link)},
{disc_copies, node()}]). % note no list here, should be [node()]
You may need to change the schema table to disc_copies which seems to affect the entire node.
mnesia:change_table_copy_type(schema, node(), disc_copies)
From the mnesia docs:
This function can also be used to change the storage type of the table named schema. The schema table can only have ram_copies or disc_copies as the storage type. If the storage type of the schema is ram_copies, no other table can be disc-resident on that node.
After this, you should be able to create disc_copies tables on the node.
Problem statement
I have a mnesia backup file and would like to extract values from it. There are 3 tables(to make it simple), Employee, Skills, and attendance. So the mnesia back up file contains all those data from these three tables.
Emplyee table is :
Empid (Key)
Name
SkillId
AttendanceId
Skill table is
SkillId (Key)
Skill Name
Attendance table is
Code (Key)
AttendanceId
Percentage
What i have tried
I have used
ets:foldl(Fetch,OutputFile,Table)
Fetch : is separate function to traverse the record fetched to bring in desired output format.
OutputFile : it writes to this file
Table : name of the table
Expecting
I am gettig records with AttendanceId(as this is the key) where as i Want to get code only. It displays employee informations and attendance id.
Help me out.
Backup and restore is described in the mnesia user guide here.
To read an existing backup, without restoring it, use mnesia:traverse_backup/4.
1> mnesia:backup(backup_file).
ok
2> Fun = fun(BackupItems, Acc) -> {[], []} end.
#Fun<erl_eval.12.90072148>
3> mnesia:traverse_backup(backup_file, mnesia_backup, [], read_only, Fun, []).
{ok,[]}
Now add something to the Fun to get what you want.
I am using mnesia table.This table has two attributes(primary key and its value).
Now i am trying delete a tuple from mnesia table.I am using delete/1 function of mnesia for deletion purpose.This function takes table name and key corresponding to tuple fro which deletion has to be made.My problem is how can i handle the scenrio when tuple corresponding to passed key is not present.This delete function gives {atomic,ok} every time?
For your case you have to read the record first and delete it only after that. To prevent an access to the record from other transactions between 'read' and 'delete' operations use 'write' lock kind when you are reading the record. It gives your transaction an exclusive access to it:
delete_record(Table, Key) ->
F = fun () ->
case mnesia:read(Table, Key, write) of
[Record] ->
mnesia:delete({Table, Key}),
{ok, Record};
[] ->
mnesia:abort(not_exist)
end
end,
mnesia:transaction(F).
-record(ng, {ng}).
mnesia:create_table(ng, [{type, set}, {attributes, record_info(fields, ng)}]).
I'm getting: {aborted,{bad_type,ng,{attributes,[ng]}}} error.
What's wrong? How to create a mnesia table with one column(which is named)?
The record has to have at least 2 fields. This would work:
-record(ng, {ng, extrafield}).
mnesia:create_table(ng, [{type, set}, {attributes, record_info(fields, ng)}]).
From http://www.erlang.org/doc/man/mnesia.html#create_table-2
"The table must have at least one extra attribute in addition to the key."
Edit: Can't find an answer as to whether a single column is possible, but this 2007 thread indicates not.
I personally do it with key/value columns, like this:
-record(proximaglobal, {key, value}).
mnesia:create_table(proximaglobal, [{attributes, record_info(fields, proximaglobal)}, {disc_only_copies, [node()]}]).
mnesia:sync_transaction(fun() -> mnesia:write(#proximaglobal{key=time, value=WorldTime}) end).
mnesia:sync_transaction(fun() -> mnesia:read(proximaglobal, time) end).
{attributes, AtomList} a list of the attribute names for the records that are supposed to populate the table. The default value is [key, val]. The table must have at least one extra attribute in addition to the key.
I want to create the following schema in Mnesia. Have three tables, called t1, t2 and t3, each of them storing elements of the following record:
-record(pe, {pid, event}).
I tried creating the tables with:
Attrs = record_info(fields, pe),
Tbls = [t1, t2, t3],
[mnesia:create_table(Tbl, [{attributes, Attrs}]) || Tbl <- Tbls],
and then write some content using the following line (P and E have values):
mnesia:write(t1, #pe{pid=P, event=E}, write)
but I got a bad type error. (Relevant commands were passed to transactions, so it's not a sync problem.)
All the textbook examples of Mnesia show how to create different tables for different records. Can someone please reply with an example for creating different tables for the same record?
regarding your "DDT" for creating the tables, I don't see any mystake at first sight, just remember that using tables with names different from the record names makes you lose the "simple" commands (like mnesia:write/1) because they use element(1, RecordTuple) to retrieve table name.
When defining tables, you can use option {record_name, RecordName} (in your case: {record_name, pe}) to tell mnesia that first atom in tuple representing records in table is not the table name, but instead the atom you passed with record_name; so in case of your table t1 it makes mnesia expecting 'pe' records when inserting or looking up for records.
If you want to insert a record in all tables, you might use a script similar to the one used to create table (but in a function wrapper for mnesia transaction context):
insert_record_in_all_tables(Pid, Event, Tables) ->
mnesia:transaction(fun() -> [mnesia:write(T, #pe{pid=Pid, event=Event}, write) || T <- Tables] end).
Hope this helps!