views:

576

answers:

6

I have two mysql databases that have almost the same structure and representing the data of the same web app but one of them represents the current version and second one was made long time ago.

How can I create the database with both dumps inside but with old_ prefix for tables from the first and new_ prefix for tables from the second database?

Is there any mysqldump options to setup the prefix or other solution?

A: 

Import them into different databases. Say they're called newdb and olddb. Then you can copy table1 to old_table1 like:

insert into newdb.old_table1
select *
from olddb.table1

If you have a huge number of tables, generate a script to copy them:

select concat('insert into newdb.old_',  table_name,
    'select * from olddb.', table_name, ';')
from information_schema.tables
where table_schema = 'olddb'
Andomar
+1  A: 

A "mysqldump file" is just a text file full of SQL statements, so you can make quick modifications like these in a text editor.

1) Dump the two databases individually.

2) Edit the "old" dump file:

  • add the correct use mydatabase; line
  • do a search and replace to add old_ in front of the table names.

3) Then, cat dump1 dump2 > combined_dump

4) mysql < combined_dump

Seth
+1 these files can be very big, however, make sure you use a decent text editor (notepad++ for example) to make the changes. Another alternative is to use the '--no-data' flag for one dump, and the '--no-create-info' for a second dump. This will give you a smaller file to do the initial editing in, and let you make sure you're creating exactly what you want. MAKE SURE to change the names of the second file's tables, otherwise you may end up putting the contents of the old file in the new file's tables.
aronchick
@aronchick +1 on bigness. Some editors absolutely crash and burn when they encounter a line that's several megabytes long (the data in mysqldump files is a huge insert statement, all on one line).
Seth
A: 

I have done the following using mysqldump and sed in the past, but I'll admit it may only be effective for one table at a time.

$ mysqldump -u user --password=mypass MyDB MyTable | sed s/MyTable/old_Mytable/ | mysql -u other_user -p NewDB

You could create a shell script with a list of the commands, one for each table, or perhaps another user has a way to modify this to work against multiple tables effectively in one shot.

Peer

Peer Allan
A: 
  1. Restore both the databases as it is.
  2. Use the following stored procedure to move all the tables from one DB to another DB after adding the prefix.
  3. After moving delete the source database.

This stored procedure gets the table list from MySQL's inmemory tables in information_schema and automatically moves to another DB using the RENAME command.

DELIMITER $$

USE `db`$$

DROP PROCEDURE IF EXISTS `renameDbTables`$$

CREATE DEFINER=`db`@`%` PROCEDURE `renameDbTables`(
    IN from_db VARCHAR(20),
    IN to_db VARCHAR(30),
    IN to_name_prefix VARCHAR(20)
)
BEGIN
/*
call db.renameDbTables('db1','db2','db_'); 
db1.xxx will be renamed to db2.db_xxx
*/
    DECLARE from_state_table VARCHAR(20) DEFAULT '';
    DECLARE done INT DEFAULT 0;
    DECLARE b VARCHAR(255) DEFAULT '';
    DECLARE cur1 CURSOR FOR SELECT TABLE_NAME FROM information_schema.TABLES 
     WHERE TABLE_SCHEMA=from_db;
    DECLARE CONTINUE HANDLER FOR SQLSTATE '02000' SET done = 1;

    OPEN cur1;

    REPEAT
     FETCH cur1 INTO from_state_table;
     IF NOT done THEN
--    select from_state_table;
      SET @QUERY = '';
      SET @QUERY = CONCAT(@QUERY,'RENAME TABLE ',from_db,'.', from_state_table,' TO ',to_db,'.', to_name_prefix, from_state_table,';');
--    SELECT @query;
      PREPARE s FROM @QUERY;
      EXECUTE s;
      DEALLOCATE PREPARE s;
     END IF;
    UNTIL done END REPEAT;
    CLOSE cur1;
    END$$

DELIMITER ;
Harun Prasad
A: 

I may be misunderstanding the problem, but it sounds like you want to dump the 2 databases into a single SQL file to be used to restore the dbs, with the old tables going into one schema and the new tables going into another.

IF that's what you are trying to do, the simplest approach is just to insert the proper "use database" command before each dump.

Like so:

echo "use old_db;" > /tmp/combined_dump.sql
mysqldump old_db >> /tmp/combined_dump.sql
echo "use new_db;" >> /tmp/combined_dump.sql
mysqldump new_db >> /tmp/combined_dump.sql
Ike Walker
A: 

This sed script is perhaps a little safer. Save it to a file and use sed -f to filter the dump file.

s/\(-- Table structure for table `\)\([^`]\+\)\(`\)/\1xyzzy_\2\3/
s/\(DROP TABLE IF EXISTS `\)\([^`]\+\)\(`\)/\1xyzzy_\2\3/
s/\(CREATE TABLE `\)\([^`]\+\)\(` (\)/\1xyzzy_\2\3/
s/\(-- Dumping data for table `\)\([^`]\+\)\(`\)/\1xyzzy_\2\3/
s/\(\/\*!40000 ALTER TABLE `\)\([^`]\+\)\(` DISABLE KEYS \*\/\)/\1xyzzy_\2\3/
s/\(LOCK TABLES `\)\([^`]\+\)\(` WRITE\)/\1xyzzy_\2\3/
s/\(INSERT INTO `\)\([^`]\+\)\(` VALUES (\)/\1xyzzy_\2\3/
s/\(\/\*!40000 ALTER TABLE `\)\([^`]\+\)\(` ENABLE KEYS \*\/\)/\1xyzzy_\2\3/

Search and replace xyzzy_ with your desired table prefix.

Cedar Myers