Check for changes in database schema and update - php

At our company we have a business solution which includes CMS, CRM and several other systems.
These are installed in several domains, for each of our clients.
The systems are still in development, so new tables and fields are added to the database.
Each time we want to release a new version to our clients, i have to go through their database and insert the new fields and tables manually.
Is there a way that this could be done automatically(a script maybe that detects the new fields and tables and inserts them?)
We are using php and mysql.
We would like to avoid backing up the clients data, dropping the database tables, running the sql query to insert all the database tables(including the new ones) and then re-inserting the customers data. Is this possible?

Toad for MySQL
DB Extract, Compare-and-Search Utility — Lets you compare two MySQL databases, view the differences, and create the script to update the target.

What you are looking for is
ALTER TABLE 'xyz' ADD 'new_colum' INT(10) DEFAULT '0' NOT NULL;
or if you want to get rid of a colum
ALTER TABLE 'xyz' DROP 'new_colum';
Put all table edits into an update.php file and the either call and delete it once manually or try to select "new_colum" once and update the database when it's not present.
OR what I do: "I have a settingsfield "software version" and use this as a trigger to update my tables.
But since you have to install the new scripts anyways you can just call it manually.

Related

MySQL table from phpMyAdmin's tracking reports

Using phpMyAdmin I can track a certain table's transactions (new inserts, deletes, etc), but is it possible to change or export it to a SQL table to be imported into my site using PHP.
While it is not exactly what I was looking for, I found a way to do it for the time being, one of the tables in the phpmyadmin (it's own) database is called pma__tracking, which contains a record of all tables being tracked, one of its columns is the data_sql longtext column which writes each report (ascendingly which is a bit annoying) in the following format
# log date username
data definition statement
Just added it for future references.

How can I compare a mysql table between two databases and update the differences efficiently?

Here is the setup, I have multiple online stores that I would like to use the same product database. Currently they are all separate, so updating anything requires going through and copying products over, it is a giant pain. What I would like to do is create a master product database that every night, each site will compare its database with, and make updates accordingly.
The idea is one master database of products that will be updated a few times a day, and then say at 2:00 AM, a cron job will run pulling the updates to the individual websites.
Just a few more details on the database, there is one table 'products' that needs to be compared, but it also needs to look at table 'prodcuts_site_status' to determine the value for the products status for each given site, so I can't simply dump the master table and re-important it into the site databases.
Creating a php script to go row by row and compare and update would be easy enough, but I was hoping there existed a more elegant/efficient solution in mysql. Any suggestions?
Thanks!
To sum up you could try 3 different methods:
use SELECT ... INTO OUTFILE and then LOAD DATA INFILE from MySQL Cross Server Select Query
use the replication approach described here Perl: How to copy/mirror remote MYSQL table(s) to another database? Possibly different structure too?
use a FEDERATED storage engine to join tables from different servers http://dev.mysql.com/doc/refman/5.0/en/federated-storage-engine.html

How to sync mysql table fields with prefix

I want ask that, is there any easy way to synchronize mysql table fields?
Let me extend my question:
I have a mysql database driven site, and I want to use my table for more than one content provider (I can use only one table because of hosting features) by separating table prefix (like Wordpress does).
I need a way to copy all fields from current table and add a prefix (I'll specify) to all new entries (E.g : there are 2 fields, links, pages and I want to add new fields new_links, new_pages to current table automatically / all keys must be the same (I mean field id's, values etc..)).
After creating those fields, there should be a way to control that, if one or more new entry was added to original fields then new fields should be created in prefixed (new_) fields.
I'm not 100% sure that I'm getting the issue, but...
Adding two new columns to the table shouldn't be a problem:
ALTER TABLE foo ADD COLUMN new_links ...
You could keep them in sync from your application (problematic) or via a trigger.
Definitely time to upgrade hosting providers.

Create Table Else Alter Table

This seems to be a simple problem, but after a while of searching I can't figure out the answer.
I currently have a MySQL table in my local database used by a webapp, and them same table on a database in a remote server. Right now, I'm using the CREATE TABLE IF NOT EXISTS command through PHP to create the table on the databases:
CREATE TABLE IF NOT EXISTS users (
`id` int(10) NOT NULL AUTO_INCREMENT,
`username` varchar(18) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ;
However, let's say I make a modification to the local database, adding a collumn, for example. It would be really annoying to have to go and change the remote database every time I change the local one. Is there an easier way to run code to create a table if it doesn't exist, and if it does exist, make sure it's structure matches that of the create table structure?
Here's an example, to make what I'm trying to convey a little clearer. Let's say on the local database I have a users table, and I decide that in my webapp I want to have another collumn, password. So I go to the local database and add a password collumn. Is there PHP/MySQL code I can run to check if the users table exists, and if it does, make sure it has a password collumn, and if not, add it?
What you are actually looking for are Migrations, e.g. you are looking for a Schema Management Tool that lets you manage your Database structure in versioned code diffs.
For instance, for your described scenario you would first create a script to create the table, e.g. 001_create_user_table.sql. Then you'd use the schema manager to connect and deploy these changes to your databases.
When you want to change or add something, you just write another script, for instance, 002_Add_Password_Column_To_User_Table.sql. Fill in just the code to do that change. Then run the schema manager again.
Typically, you tell the Schema Manager to go through all existing migrations files. On each run, the Schema manager will update a changelog table in the database, so when you run it, it will know which of your scripts it should apply.
The good thing is, you can add these migrations to your regular VCS, so you will always know which database schema you had at which version of your application. And you will have a proper changelog for them.
To directly answer your question you can create temporary procedures to detect field existence like using a query like this:
SHOW COLUMNS FROM table_name LIKE 'column_name';
However in the real world, database changes are general rolled into three scripts. A create script and two deltas one up and one down. Then the database is versioned so that you know at what state the database is in at any given time.
To specifically check for a password column you can use DESCRIBE:
$colExists = false;
$res = mysql_query('DESCRIBE `users`');
while ($row = mysql_fetch_assoc($res)) {
if ($row['Field'] == 'password') {
$colExists = true;
break;
}
}
if (!$colExists) {
// create column
}
However, you should check into replication or some other automated tool to see if they would be a better solution for you.
Follow these steps (you can easily implement this in PHP, I assumed that the name of the table is Foo)
1.) Run the following code:
desc Foo
2.) Based on the result of the first step you can make your create table command (and you should)
3.) Store your data from the existing table which will be replaced in a variable (Optional, you only need this if you can potentially use data from the old table)
4.) Modify the extracted rows from step 3.) so they will be compatible with your new definition (Optional, you only need this if you can potentially use data from the old table)
5.) Get the rows from your new Foo table
6.) Merge the results got in steps 4.) an 5.) (Optional, you only need this if you can potentially use data from the old table)
7.) Run a drop table for the old table
8.) Generate a replace into command to insert all your rows into the newly created Foo table (you can read more about this here)
After these steps, as a result, you will have the new version of the table. If your tables are too large, you can do a CREATE TABLE IF NOT EXISTS command and if that was not successful, run the alter command.
Also, you can make a library to do these steps and will use that in the future instead of solving the same problem several times.
EDIT:
You can connect the database using this function: mysql-connect (documentation here)
You can run a query using this function: mysql-query (documentation here)
Based on the first step you will get the field names (let's assume you store it in a variable called $bar) and you can use your result to generate your select command (connecting to the database where you have important data. It may be both):
$field_list = "1";
foreach ($bar as $key => $value)
$field_list.= ",".$bar[$key];
mysql_connect(/*connection data*/);
mysql_query("select ".$field_list." from Foo");
You can use your new resource to build up an insert command to insert all your important data after deletion recreation (about resources read more here, about how you can generate your insert you can read here, but I suggest that you should use replace into instead of insert which works like the insert, except that it replaces the row if it already exists, it's better here than an insert, read more here)
So, use mysql_connect and mysql_query, and the resource returned by the mysql_query function can be used for replace into later (I've linked now the URL's for everything you need, so I'm pretty sure you'll solve the problem.), apologies for being not specific enough before.

import mysql data to a table, edit/clone rows, and insert new rows

Is there already any software that will allow me to select a table or row from existing DB, edit that table, add new rows, or clone existing ones, then insert the new rows back into the DB?
Read: i want to ADD this data, do not want to update/replace existing data.
PHP5, and MySQL 5
There's PHPMyAdmin, which will let you to pretty much anything to a database.
You can clone rows by editing and selecting "insert as new row" (may have to blank out the primary key if you have one).
MySQL Administrator is a decent GUI put out by MySQL that should handle all of that. I'm quite happy with it.
There's also HeidiSQL which is a windows client for managing MySQL databases:
http://www.heidisql.com/
And there's jHeidi from the same site that's java based and so should run on other operating systems.

Categories