Giter VIP home page Giter VIP logo

dbdiff's Introduction

DBDiff logo

Build Status Total Downloads Monthly Downloads License

DBDiff is an automated database schema and data diff tool. It compares two databases, local or remote, and produces a migration file of the differences automatically.

When used alongside a compatible database migration tool, it can help enable database version control within your team or enterprise.

Supporting DBDiff

DBDiff is a MIT-licensed open source project with its ongoing development made possible entirely by the support of backers. For getting a mention in return, please consider:

Features

  • Works on Windows, Linux & Mac command-line/Terminal because it has been developed in PHP
  • Connects to a source and target database to do the comparison diff, locally and remotely
  • Diffs can include changes to the schema and/or data, both in valid SQL to bring the target up-to-date with the source
  • Some tables and/or fields can be ignored in the comparison with a YAML collection in the config file (see File Examples)
  • Diffs are SUPER fast and this tool has been tested with databases of multiple tables of millions of rows
  • Since this diff tool is being used for migrations, it provides up and down SQL in the same file
  • Works with existing migration tools like Flyway and Simple DB Migrate by specifying output template files/formats, for example, Simple DB Migrate may work with simple-db-migrate.tmpl which includes: SQL_UP = u""" {{ $up }} """ SQL_DOWN = u""" {{ $down }} """
  • Is Unicode aware, can work with UTF8 data, which includes foreign characters/symbols
  • Works with just MySQL for now, but we will be expanding to other DBs in the future on request (please create an issue and vote on it!)

Pre-requisites

  1. You will need to have access to the command-line, for Linux/Mac a Terminal or on Windows it will be a command prompt (cmd)
  2. You will need to have git installed: http://git-scm.com/downloads
  3. You will need to have PHP installed (version 5.4.x): http://php.net/manual/en/install.php
  4. You will need to have Composer installed which is a Dependency Manager for PHP: https://getcomposer.org

Note: Make a note of where composer.phar is installed as we will need it later on during Setup

Installation

On the command-line, use git to clone the ssh version:

git clone [email protected]:DBDiff/DBDiff.git

Or use git to clone the https version:

git clone https://github.com/DBDiff/DBDiff.git

Or download the .zip archive and unzip it to a folder of your choosing e.g. dbdiff:

https://github.com/DBDiff/DBDiff/archive/master.zip

Or use composer to include DBDiff as a project dependency:

php composer.phar require "dbdiff/dbdiff:@dev"

Or use composer to install DBDiff globally:

composer global require "dbdiff/dbdiff:@dev"

Create a PHAR build

Please first ensure in your php.ini file the phar.readonly setting is set to false , for example:

[Phar]
; http://php.net/phar.readonly
phar.readonly = false

Then in the root of the dbdiff repository to produce a Phar build simply run:

$ ./build

A dist folder should be created containing the following files:

  • dbdiff.phar
  • dbdiff.phar.gz

Feel free to rename dbdiff.phar to dbdiff and move it to /usr/local/bin or another directory of your choice.

You can also add it to your system's path if you wish to make it globally available on your system as a utility.

Setup

Make sure you are in the root of your application for all the following steps, using 'cd' to navigate on the command line to where you have placed your "dbdiff" folder

We are going to assume that composer.phar is installed inside your "dbdiff" folder. If it is installed elsewhere you will need to use it's exact path

  1. If you didn't install DBDiff with composer, install the dependencies of the project with: php composer.phar install
  2. Make a .dbdiff file by following the File Examples and place it in the root of your "dbdiff" directory
  3. Type ./dbdiff {dbdiff command here e.g. server1.db1:server1.db2} to start the app! See Command-Line API for more details on which commands you can run.

You should see something like...

ℹ Now calculating schema diff for table `foo`
ℹ Now calculating data diff for table `foo`
ℹ Now generating UP migration
ℹ Now generating DOWN migration
ℹ Writing migration file to /path/to/dbdiff/migration.sql
✔ Completed

Congratulations you have installed and ran DBDiff!

Command-Line API

Note: The command-line parameters will always override the settings in the .dbdiff config file
  • --server1=user:password@host1:port - Specify the source db connection details. If there is only one server the --server1 flag can be omitted
  • --server2=user:password@host2:port - Specify the target db connection details (if it’s different to server1)
  • --template=templates/simple-db-migrate.tmpl - Specifies the output template, if any. By default will be plain SQL
  • --type=schema or data or all - Specifies the type of diff to do either on the schema, data or both. schema is the default
  • --include=up or down or all - Specified whether to include the up, down or both data in the output. up is the default
  • --nocomments=true - By default automated comments starting with the hash (#) character are included in the output file, which can be removed with this parameter
  • --config=config.yaml - By default, DBDiff will look for a .dbdiff file in the current directory which is valid YAML, which may also be overridden with a config file that lists the database host, user, port and password of the source and target DBs in YAML format (instead of using the command line for it), or any of the other settings e.g. the format, template, type, include, nocomments. Please note: a command-line parameter will always override any config file.
  • server1.db1.table1:server2.db2.table3 or server1.db1:server2.db2 - The penultimate parameter is what to compare. This tool can compare just one table or all tables (entire db) from the database
  • --output=./output-dir/today-up-schema.sql - The last parameter is an output file and/or directory to output the diff to, which by default will output to the same directory the command is run in if no directory is specified. If a directory is specified, it should exist, otherwise an error will be thrown. If this path is not specified, the default file name becomes migration.sql in the current directory

Usage Examples

Example 1

$ ./dbdiff server1.db1:server2.db2

This would by default look for the .dbdiff config file for the DB connection details, if it’s not there the tool would return an error. If it’s there, the connection details would be used to compare the SQL of only the schema and output a commented migration.sql file inside the current directory which includes only the up SQL as per default

Example 2

$ ./dbdiff server1.development.table1:server2.production.table1 --nocomments=true --type=data

This would by default look for the .dbdiff config file for the DB connection details, if it’s not there the tool would return an error. If it’s there, the connection details would be used to compare the SQL of only the data of the specified table1 inside each database and output a .sql file which has no comments inside the current directory which includes only the up SQL as per default

Example 3

$ ./dbdiff --config=config.conf --template=templates/simple-db-migrate.tmpl --include=all server1.db1:server2.db2 --output=./sql/simple-schema.sql

Instead of looking for .dbdiff, this would look for config.conf (which should be valid YAML) for the settings, and then override any of those settings from config.conf for the --template and --include parameters given in the command-line parameters - thus comparing the source with the target database and outputting an SQL file called simple-schema.sql to the ./sql folder, which should already exist otherwise the program will throw an error, and which includes only the schema as an up and down SQL diff in the simple-db-migrate format (as specified by the template). This example would work perfectly alongside the simple-db-migrate tool

File Examples

.dbdiff

server1:
	user: user
	password: password
	port: port # for MySQL this is 3306
	host: host1 # usually localhost or 127.0.0.1
server2:
	user: user
	password: password
	port: port # for MySQL this is 3306
	host: host1 # usually localhost or 127.0.0.1
template: templates/simple-db-migrate.tmpl
type: all
include: all
nocomments: true
tablesToIgnore:
- table1
- table2
- table3
fieldsToIgnore:
	table1:
		- field1
		- field2
		- field3
	table4:
		- field1
		- field4

simple-db-migrate.tmpl

SQL_UP = u"""
{{ $up }}
"""
SQL_DOWN = u"""
{{ $down }}
"""

How Does the Diff Actually Work?

The following comparisons run in exactly the following order:

  • When comparing multiple tables: all comparisons should be run
  • When comparing just one table with another: only run the schema and data comparisons

Overall Comparison

  • Check both databases exist and are accessible, if not, throw an error
  • The database collation is then compared between the source and the target and any differences noted for the output

Schema Comparison

  • Looks to see if there are any differences in column numbers, name, type, collation or attributes
  • Any new columns in the source, which are not found in the target, are added

Data Comparison

  • And then for each table, the table storage type (e.g. MyISAM, CSV), the collation (e.g. utf8_general_ci), and number of rows are compared, in that order. If there are any differences they are noted before moving onto the next test
  • Next, both changed rows as well as missing rows from each table are recorded

Compatible Migration Tools

Project Language / Package Manager Description
Simple DB Migrate Python / PIP Generic database migration tool inpired on Rails migrations
Flyway Java / Maven Database Migrations Made Easy

Please do let us know if you're using any other migration tools with DBDiff, other than the ones listed here, so we can add it.

Questions & Support 💭

  • The documentation so far is what you see on this page, however this will slowly be expanded onto it's own website
  • If you are a company or organisation interested in commercial support packages for DBDiff please get in touch

Backers 💕

Sean McNamara

Back DBDiff on Patreon and have your name or logo displayed prominently here!

Contributions 💞

Please make sure to read the Contributing Guide before making a pull request.

Thank you to all the people who already contributed to DBDiff!

Feedback 💬

If you've made it down here, you're probably a fan 😉

Could you please kindly spare 2 minutes to give us your feedback on DBDiff:

https://forms.gle/gjdJxZxdVsz7BRxg7

We read each and every suggestion that comes through.

License

MIT

Made with  :heart:  by   Akal Software logo

dbdiff's People

Contributors

amontalban avatar desyncr avatar jasdeepkhalsa avatar jawb avatar jijoel avatar plashenkov avatar webian avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dbdiff's Issues

Migration PHINX

Hello
Perhaps to add automatic generation of file migration PHINX?

Robert.

Support for wildcards on tableToIgnore / columnToIgnore

Would be nice if the code supported regex-based table/column ignore. We have tables that are generated with a prefix followed by some hash (_tmp_1477937742941_0dbe9593_J as an example). Would be nice to be able to ignore all "tmp%" tables when doing comparisons.

A Symfony error about indentation with tabs

Hi, I ran this: php dbdiff server1.db1:server1.db2 and got an error about indentation with tabs

> php dbdiff server1.db1:server1.db2
✖ Unexpected error: A YAML file cannot contain tabs as indentation at line 27 (near "           ").

Fatal error: Uncaught Symfony\Component\Yaml\Exception\ParseException: A YAML file cannot contain tabs as indentation at line 27 (near "                "). in C:\dbdiff\DBDiff\vendor\symfony\yaml\Parser.php:125
Stack trace:
#0 C:\dbdiff\DBDiff\vendor\symfony\yaml\Parser.php(80): Symfony\Component\Yaml\Parser->doParse('output.sql', false, false, false)
#1 C:\dbdiff\DBDiff\vendor\symfony\yaml\Yaml.php(65): Symfony\Component\Yaml\Parser->parse('server1:\r\n user...', false, false, false)
#2 C:\dbdiff\DBDiff\src\Params\FSGetter.php(19): Symfony\Component\Yaml\Yaml::parse('server1:\r\n user...')
#3 C:\dbdiff\DBDiff\src\Params\ParamsFactory.php(20): DBDiff\Params\FSGetter->getParams()
#4 C:\dbdiff\DBDiff\src\DBDiff.php(18): DBDiff\Params\ParamsFactory::get()
#5 C:\dbdiff\DBDiff\dbdiff(8): DBDiff\DBDiff->run()
#6 {main}
  thrown in C:\dbdiff\DBDiff\vendor\symfony\yaml\Parser.php on line 125

How can I fix this?

DBDiff does not work for me

Hey,

I'm trying DBDiff to see if we can use it in our push to production process and I can't get it to work:

root@47db20dcad75:/DBDiff# ./dbdiff --debug --server1=root:[email protected]:32789 --server2=root:[email protected]:32790 --type=all server1.employees:server2.employees
✖ Can't connect to target database

It seems that it fails to connect (I also tried by creating .dbdiff config file with following content):

server1-user: root
server1-password: secret
server1-port: 32789
server1-host: 192.168.1.5
server2-user: root
server2-password: secret
server2-port: 32790
server2-host: 192.168.1.5
template: templates/simple-db-migrate.tmpl
type: all
include: all
no-comments: true

But as you can see the MySQL client can connect just fine to both servers (Docker instances):

root@47db20dcad75:/DBDiff# mysql -h 192.168.1.5 -u root -psecret -P32789 -e "show databases; select @@hostname;"
+--------------------+
| Database           |
+--------------------+
| information_schema |
| employees          |
| mysql              |
| performance_schema |
+--------------------+
+--------------+
| @@hostname   |
+--------------+
| 9b76c1977e66 |
+--------------+
root@47db20dcad75:/DBDiff# mysql -h 192.168.1.5 -u root -psecret -P32790 -e "show databases; select @@hostname;"                                                                                                                              
+--------------------+
| Database           |
+--------------------+
| information_schema |
| employees          |
| mysql              |
| performance_schema |
+--------------------+
+--------------+
| @@hostname   |
+--------------+
| 2601fdf05b85 |
+--------------+

Am I missing something?

help installing on windows please?

where did i go wrong?

  1. created a new folder under c:\wamp\www\ called dbdiff
  2. in cmd win, i navigate to c:\wamp\www\dbdiff\ and execute: git clone https://github.com/DBDiff/DBDiff.git
    it installs with no errors.
  3. in cmd win, i navigate to c:\wamp\www\dbdiff\DBDiff\ and execute: composer install
    everything installs with no errors.
  4. i created '.dbdiff' file in c:\wamp\www\dbdiff\DBDiff\ (or should it be created in www\dbdiff\ folder?)
  5. i set my db params for both servers in .dbdiff file and save it.
  6. in cmd win, from c:\wamp\www\dbdiff\DBDiff\ folder i type: ./dbdiff
    windows gives message that '.' is not recognized as an internal or external command.

thank you for any help

Can't connect to target database

Here is the command I run that generates the above error message:
./dbdiff server1.dev:server2.prod

My .dbcon is setup as such:

server1:
user: root
password:
port: 3306 # for MySQL this is 3306
host: localhost # usually localhost or 127.0.0.1
server2:
user: root
password:
port: 3306 # for MySQL this is 3306
host: localhost # usually localhost or 127.0.0.1
template: templates/simple-db-migrate.tmpl
type: all
include: all
nocomments: true
tablesToIgnore:
-accesslog
-users

This is a test vm and mysql actually has no password set on it so the field is left empty, I'm assuming this isn't the problem?

Its also unclear which of the two databases is the source and which is the target.

Any help would be great.

Can't install via composer: Installation request for symfony/symfony (installed at v3.4.3, required as 3.4.*) -> satisfiable by symfony/symfony[v3.4.3].

Steps to reproduce:

$ composer create-project symfony/framework-standard-edition test

$ composer require "dbdiff/dbdiff:@dev"

Log:

./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Conclusion: don't install dbdiff/dbdiff dev-master
    - Conclusion: remove symfony/symfony v3.4.3
    - Installation request for dbdiff/dbdiff @dev -> satisfiable by dbdiff/dbdiff[dev-better-ci-coverage, dev-master].
    - Conclusion: don't install symfony/symfony v3.4.3
    - dbdiff/dbdiff dev-better-ci-coverage requires symfony/yaml 2.8.*@dev -> satisfiable by symfony/yaml[v2.8.0, v2.8.1, v2.8.10, v2.8.11, v2.8.12, v2.8.13, v2.8.14, v2.8.15, v2.8.16, v2.8.17, v2.8.18, v2.8.19, v2.8.2, v2.8.20, v2.8.21, v2.8.22, v2.8.23, v2.8.24, v2.8.25, v2.8.26, v2.8.27, v2.8.28, v2.8.29, v2.8.3, v2.8.30, v2.8.31, v2.8.32, v2.8.33, v2.8.4, v2.8.5, v2.8.6, v2.8.7, v2.8.8, v2.8.9].
    - don't install symfony/yaml v2.8.0|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.1|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.10|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.11|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.12|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.13|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.14|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.15|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.16|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.17|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.18|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.19|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.2|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.20|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.21|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.22|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.23|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.24|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.25|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.26|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.27|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.28|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.29|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.3|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.30|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.31|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.32|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.33|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.4|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.5|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.6|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.7|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.8|don't install symfony/symfony v3.4.3
    - don't install symfony/yaml v2.8.9|don't install symfony/symfony v3.4.3
    - Installation request for symfony/symfony (locked at v3.4.3, required as 3.4.*) -> satisfiable by symfony/symfony[v3.4.3].


Installation failed, reverting ./composer.json to its original content.

windows 10 64 bit incompatiable

Just installed, everything,

php 5.6.3
composer 1.4.1

I installed the dependencies using composer install

I setup my .dbdiff configuration file

When i tried running it from the command line , i got
'dbdiff' is not recognized as an internal or external command,
operable program or batch file.

I renamed dbdiff to dbdiff.exe and ran it again and was told the dbdiff is a 16 bit application that is incompatiable with 64 bit windows

image

append

Hi first of all let me start saying your tool looks very promising especially the level of description and details written. Before i jump into installing every thing and trying I have few simple questions and your answer will be highly appreciated .

  1. Does it support append as output sql ?
  2. Does it support innodb ?

Order of Fields while Calculating MD5

In DBManager.php, DBDiff uses SHOW COLUMNS FROM $table to get columns.
Considering the following databases,

DB1:

CREATE TABLE IF NOT EXISTS `aa` (
  `id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `pass` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `aa` (`id`, `name`, `pass`) VALUES (1, 'aa', 'zz');

DB2:

CREATE TABLE IF NOT EXISTS `aa` (
  `id` int(11) NOT NULL,
  `pass` varchar(255) DEFAULT NULL,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

INSERT INTO `aa` (`id`, `name`, `pass`) VALUES (1, 'aa', 'zz');

The columns of DB1 is (id, name, pass), and the columns of DB2 is (id, pass, name).
Therefore the MD5 values are MD5('1aazz') for DB1 and MD5('1zzaa').

After calculating diff data column by column, DBDiff will find that the two records are equal.
But DBDiff will still generate SQL

SQL_UP = u"""
UPDATE `aa` SET  WHERE `id` = '1';
"""
SQL_DOWN = u"""
UPDATE `aa` SET  WHERE `id` = '1';
"""

which is not a valid syntax.

I think you can sort the columns before concatenating the columns.
In getChangeDiff in LocalTableData.php, add

        asort($columns1);
        asort($columns2);
        $columnsA   = implode(',', $wrapCast($columns1, 'a'));
        $columnsB   = implode(',', $wrapCast($columns2, 'b'));

Update:
And when we insert data, order of fields should explicitly specified.

Wrong DELETE on non existent table

Hey guys,

I'm doing some tests with this great tool and I found this issue:

Server 1 (Source):

mysql> show tables like '%all_data_20160803132410%';
Empty set (0.02 sec)

mysql> select count(*) from all_data_20160803132410;
ERROR 1146 (42S02): Table 'ales68.all_data_20160803132410' doesn't exist

Server 2 (Destination):

mysql> show tables like '%all_data_20160803132410%';
+----------------------------------------------+
| Tables_in_ales68 (%all_data_20160803132410%) |
+----------------------------------------------+
| all_data_20160803132410                      |
+----------------------------------------------+
1 row in set (0.01 sec)

mysql> select count(*) from all_data_20160803132410;
+----------+
| count(*) |
+----------+
|        6 |
+----------+
1 row in set (0.01 sec)

I run the following command:

/usr/local/dbdiff/dbdiff [email protected]:3306 [email protected]:3306 --type=all server1.DB1:server2.DB2 --output=diff_test.sql

And it generates the following wrong output:

DELETE FROM `all_data_20160803132410` WHERE ;
DELETE FROM `all_data_20160803132410` WHERE ;
DELETE FROM `all_data_20160803132410` WHERE ;
DELETE FROM `all_data_20160803132410` WHERE ;
DELETE FROM `all_data_20160809105308` WHERE ;
DELETE FROM `all_data_20160803132410` WHERE ;
DELETE FROM `all_data_20160803132410` WHERE ;
DROP TABLE `all_data_20160803132410`;

As you can see it generates a line with the following code for EACH row on the table:

DELETE FROM `all_data_20160803132410` WHERE ;

Which is not valid and then it generates a DROP TABLE (Which should be the one that needs to be executed).

Unfortunately I can't share a dump of this data as it is confidential but have cases with tables with 44k rows and generates 44k lines of same DELETE.

Additionally I detected that when you do a simple UPDATE of a field DBDiff generates a DELETE line and an INSERT instead of doing an UPDATE, should I open a new issue for this?

Thank you very much for this great tool and let me know if more info is needed!

memory_limit

In DBDiff.php file there is a line which sets up memory_limit to 512M.

ini_set('memory_limit', '512M');

This is wrong due to on local machines sometimes we have to set it up even higher. This value should only be set up by user and not appear in the class.

Add support for triggers

Hi, this tool is great !
It's would be nice if it was also possible to have migration exports of triggers !

fieldsToIgnore not working

DBDiff version: commit c001e9f

.dbdiff file:

server1:
    ...
server2:
    ...
type: schema
include: all
nocomments: true
fieldsToIgnore:
    table_name:
        - field_name

Run with:

./vendor/dbdiff/dbdiff/dbdiff "server1.db_from:server2.db_to" --output="./migration.sql"

The ignored column field_name is still included in the migration file.

A server is required

Hello, here is my config file:

server1:
	user: root
	password:
	port: 3306
	host: localhost
server2:
	user: root
	password:
	port: 3306
	host: localhost
template: templates/simple-db-migrate.tmpl
type: schema
include: all
nocomments: true

And here is the cmd I'm trying to run
./dbdiff server1.database:server2.database-prod output=./sql/simple-schema.sql
When my config file contain tabulations, it doesn't work (yaml can't contain tabulations). When I remove them, I'm getting the error A server is required.
There is no password for now on the database, does I need to set one to use DBDiff?
Thank you for your reply.

Failed comparison if a field is NULL

If one of the fields of the analyzed record is NULL then MD5 returns NULL so even if 2 records are different they are considered equal: NULL = NULL
This happens in method getChangeDiff of class LocalTableData

Edited row in table does not compre in diff

Hello, I've tried to clone a database, edit a single value in a table row, and launch the program.
The edit passed unnoted, and no diff file was generated.

Conversely, editing the primary key of the table is noted and the diff file is generated.

The databases reside on the same (local VM) server.

How to compare database dump FILES?

From what I undertstand reading the description this interesting tool can compare database schemas ony in live databases. I would like to compare schemas from database dumps that were generated with mysqldump - is this possible?

Thanks for your attention!

About autolaod.php Path Error

Error: Failed opening required 'vendor/autoload.php'
change this execute file /vendor/dbdiff/dbdiff/dbdiff.
'vendor/autoload.php' -> '../../autoload.php'

Missing AFTER directive

While generating "ALTER TABLE" sqls, DBDIFF doesn't add "AFTER $COLUMN" directive, so every new column have been added at the end of every table.
I found "modifyAfter" function but it doesn't add that directive anyway.

Thank you for any help.

Uncaught Error: Call to undefined method Diff\DiffOp\DiffOpAdd::getOldValue() in

ℹ Now calculating schema diff for table `users`
.......................
ℹ Now calculating data diff for table `client_contacts`
.......................
ℹ Now getting new data from table `charge_items`
.......................
ℹ Now generating UP migration
ℹ Now generating DOWN migration
PHP Fatal error:  Uncaught Error: Call to undefined method Diff\DiffOp\DiffOpAdd::getOldValue() in /usr/home/*******/vendor/dbdiff/dbdiff/src/SQLGen/DiffToSQL/UpdateDataSQL.php:40
Stack trace:
#0 [internal function]: DBDiff\SQLGen\DiffToSQL\UpdateDataSQL->DBDiff\SQLGen\DiffToSQL\{closure}(Object(Diff\DiffOp\DiffOpAdd), 'customcharges')
#1 /usr/home/*********/vendor/dbdiff/dbdiff/src/SQLGen/DiffToSQL/UpdateDataSQL.php(41): array_walk(Array, Object(Closure))
#2 /usr/home/*********/vendor/dbdiff/dbdiff/src/SQLGen/MigrationGenerator.php(12): DBDiff\SQLGen\DiffToSQL\UpdateDataSQL->getDown()
#3 /usr/home/*********/vendor/dbdiff/dbdiff/src/SQLGen/SQLGenerator.php(24): DBDiff\SQLGen\MigrationGenerator::generate(Array, 'getDown')
#4 /usr/home/*********/vendor/dbdiff/dbdiff/src/DBDiff.php(36): DBDiff\SQLGen\SQLGenerator->getDown()
#5 /usr/home/*********/vendor/dbdiff/dbdiff/dbdiff(8): DBDiff\DBDiff->run()
#6 {main}
  thrown in /usr/home/*********/vendor/dbdiff/dbdiff/src/SQLGen/DiffToSQL/UpdateDataSQL.php on line 40

Dry run

Would you include a --dry-run option, so that the cli output would show that there is a difference or not in the two compared databases, but it would not generate a migration?

SSH tunnel

I have a vagrant machine (with puphpet)
The only way to connect to MySQL is via ssh tunneling, IS there a way to use dbdiff with this type of connection?

Failed to drop an indexed column

If we drop an indexed column, its index is also dropped.
For example,
Source DB:

CREATE TABLE IF NOT EXISTS `aa` (
  `id` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Target DB:

CREATE TABLE IF NOT EXISTS `aa` (
  `id` int(11) NOT NULL,
  `name` varchar(36) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `name_index` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Generated migration:

ALTER TABLE `aa` DROP `name`;
ALTER TABLE `aa` DROP INDEX `name_index`;

If we apply the migration, it fails with error message #1091 - Can't DROP 'name_index'; check that column/key exists

Incomplete Diff

Perhaps you could include an option to prevent ignoring tables that have the same count().

Order of Create Tables is wrong when using foreign keys

Just a quick test resulted in 2 tables that should be created in a different order because the first references the second in a foreign key constraint.

CREATE TABLE permissions (
action_id int(11) NOT NULL,
user_type_id int(11) NOT NULL,
PRIMARY KEY (action_id,user_type_id),
KEY FK_permissions_user_types (user_type_id),
CONSTRAINT FK_permissions_actions FOREIGN KEY (action_id) REFERENCES sec_action (ActionId),
CONSTRAINT FK_permissions_user_types FOREIGN KEY (user_type_id) REFERENCES user_types (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE user_types (
id int(11) NOT NULL AUTO_INCREMENT,
name varchar(50) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Template file limitations

I'm trying to output the up and down sql code into a CodeIgniter Migrations file. This is a php file with a class with up and down methods.

It looks like the template file can't be used when there's actual PHP code in it. Is there a way past this? Or what is the exact reason this doesn't work?

Idea: how can we make it work? If we can't, note the limitations in the documentation.

Deleting foreign key constraints, wrong order and invalid syntax

When deleting foreign key constraints, two error appear:

  1. DBDiff tries to delete the index key first and then to drop the constraint. But as MySQL still uses the constraints, it can't drop the key.

  2. Wrong Syntax for dropping the constraint, see: http://stackoverflow.com/questions/14122031/how-to-remove-constraints-from-my-mysql-table

Example: create two tables and add a foreign key, create dbdiff and see what' wrong.
ALTER TABLE order ADD FOREIGN KEY ( user_id ) REFERENCES user( id )

(great work else, love the script, helps me save a lot of time.)

Remove index, create key

For most my tables (for every index) dbdiff falsely generate lines like next:

ALTER TABLE `t` DROP INDEX `idx_a`;
ALTER TABLE `t` ADD KEY `idx_a` (`a`); 

Approaches for same server or not

Hi @jasdeepkhalsa,
I can't get the reason why you use 2 different approaches if the comparison is between same servers or different.
I mean this code in method getDiff of TableData:

if ($server1 == $server2) {
  return $this->localTableData->getDiff($table, $sourceKey);
} else {
  return $this->distTableData->getDiff($table, $sourceKey);
}

Please, can you help me to understand?

Dropping foreign key columns

Hi
When dropping foreign key columns using alter table statements, dbdiff uses "DROP CONSTRAINT". Instead, it should use "DROP FOREIGN KEY".

Diff with dump

Hi there,

Are there any plans to compare a database structure with an already existing mysqldump (e.g. in a file)?

My temp solution to this would be to create the database from the dump and then use this tool, but that doesn't feel right.

I think the solution to this would only be a small change in code to make it possible.

DBDiff says falsely tables are identical

Depending on the presence of a third field DBDiff detects or not the difference in the second field.

Step to reproduce
1°) Create the a11_elements and a12_elements tables in two databases
2°) In database2, change a value
3°) Run DBDiff

1°)

CREATE TABLE a11_elements (
id int(6) NOT NULL,
show_in_list_summary int(1) DEFAULT NULL,
filter_exact_match int(1) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO a11_elements (id, show_in_list_summary, filter_exact_match) VALUES(646, 1, NULL);
ALTER TABLE a11_elements ADD PRIMARY KEY (id);

CREATE TABLE a12_elements (
id int(6) NOT NULL,
show_in_list_summary int(1) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO a12_elements (id, show_in_list_summary) VALUES (646, 1);
ALTER TABLE a12_elements ADD PRIMARY KEY (id);

2°)

database2.a11_elements.show_in_list_summary=0
database2.a12_elements.show_in_list_summary=0

3°)

php dbdiff --server1=root:root@localhost:3306 --type=data --include=all server1.database1.a11_elements:server1.database2.a11_elements --output=dbdiff_database1to2.sql

Results :

Now calculating data diff for table a11_elements
Identical resources
Completed

php dbdiff --server1=root:root@localhost:3306 --type=data --include=all server1.database1.a12_elements:server1.database2.a12_elements --output=dbdiff_database1to2.sql

Results :

Now calculating data diff for table a12_elements
Now generating UP migration
Now generating DOWN migration
Writing migration file to dbdiff_database1to2.sql
Completed

---------- UP ----------

UPDATE a12_elements SET show_in_list_summary = '0' WHERE id = '646';

---------- DOWN ----------

UPDATE a12_elements SET show_in_list_summary = '1' WHERE id = '646';

Conclusion: With the same context for the first two fields (646 on both databases and respectively 1 / 0 on each database), only when deleting the third field DBDiff detects the difference in the second field.

source db can use sql files?

Thanks for your great work!
Our production dbs are only allowed to access in local netwrok.
We dump developing dbs to sql files and restore them to production dbs.
If source db can use sql files?

A way to specify a non-standard socket?

Just a small feature request, but it wasn't clear how to use a non-standard socket. Something like this:

server1:
   user: root
   password: root
   port: 3306
   host: localhost 
   socket: /Applications/MAMP/tmp/mysql/mysql.sock

Support for more login options

It would be great if more mysql login options could be specified in .dbdiff. Options for SSL connections would be particularly helpful. Ideally, one would be able to login using credentials stored in .mylogin.cnf. Though it appears this tool solves many of the issues of mysqldbcompare, the lack of SSL options prevents me from using it in my project.

Feature Request: Improve usability without command line

Would prefer better usability within php itself. It is weird to transfer command line paramenter when I could simply set variables. For syncing beta to production servers, I prefer a solid php script instead of opening the cli everytime.

Regards

PHP 7.x support

I haven't tested this yet, but I might be needing this tool in several PHP 7.x environments. Will this cause any problems?

Fail to find table

Hello

When using the server.db.table syntax as below DBDiff fails to find the table in a certain database.
The databasename is equal on both sides (local and remote). I am running php 5.6.29, composer 1.3.0 and latest DBDiff.

#./dbdiff server1.dbname.table1:server2.dbname.table2 --nocomments=true --type=schema

Unexpected error: SQLSTATE[42S02]: Base table or view not found: 1146 Table 'dbname.table1' doesn't exist (SQL: SHOW CREATE TABLE table1)

PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42S02]: Base table or view not found: 1146 Table 'dbname.table1' doesn't exist' in /usr/local/src/DBDiff/vendor/illuminate/database/Illuminate/Database/Connection.php:301
Stack trace:
#0 /usr/local/src/DBDiff/vendor/illuminate/database/Illuminate/Database/Connection.php(301): PDOStatement->execute(Array)
#1 /usr/local/src/DBDiff/vendor/illuminate/database/Illuminate/Database/Connection.php(617): Illuminate\Database\Connection->Illuminate\Database{closure}(Object(Illuminate\Database\MySqlConnection), 'SHOW CREATE TAB...', Array)
#2 /usr/local/src/DBDiff/vendor/illuminate/database/Illuminate/Database/Connection.php(581): Illuminate\Database\Connection->runQueryCallback('SHOW CREATE TAB...', Array, Object(Closure))
#3 /usr/local/src/DBDiff/vendor/illuminate/database/Illuminate/Database/Connection.php(304): Illuminate\Database\Connection->run('SHOW CREATE TAB...', Array, Object(Closure))
#4 /usr/local/src/DBDiff/src/DB/Schema/TableSchema.php(40): Illumi in /usr/local/src/DBDiff/vendor/illuminate/database/Illuminate/Database/Connection.php on line 625

NULL values are not handled correctly in INSERT and UPDATE statemens

When a column contains NULL values the INSERT statement always genereates quotes with an empty string.
This can be fixed in "\DBDiff\SQLGen\DiffToSQL\InsertDataSQL"
by replacing

        $values = array_map(function ($el) {
            return "'".addslashes($el)."'";
        }, $values);

with

        $values = array_map(function ($el) {
            if(!is_null($el)) {
                return "'" . addslashes($el) . "'";
            }
            else {
                return 'NULL';
            }
        }, $values);

and also in "\DBDiff\SQLGen\DiffToSQL\UpdateDataSQL" by replacing

        array_walk($values, function(&$diff, $column) {
            $diff = '`'.$column."` = '".addslashes($diff->getNewValue())."'";
        });

with

        array_walk($values, function(&$diff, $column) {
            if(!is_null($diff->getNewValue())) {
                $diff = '`' . $column . "` = '" . addslashes($diff->getNewValue()) . "'";
            }
            else {
                $diff = '`' . $column . "` = NULL";
            }
        });

Best regards,
Christian

Add a license file

It seems the MIT license is specified in composer.json, but it would be good to have a license file inside the project for clarification.

alter statement due to quotet default numbers

Thanks for your good work.
Everything works fine for me.

I only want to notice that different sql databases version (an even different versions of maria db)
sometimes write the default value with quotes and sometimes not which leads to an alter statement even if everything is equal.

this happens if you compare a mariadb 10.1 and a mariadb 10.2 server for example.

you can reproduce this when you type
SHOW CREATE TABLE test;
when 'test' is created like this for example:

CREATE TABLE `test` (
  `tinyint` tinyint(1) NOT NULL DEFAULT 0,
  `int` int(11) NOT NULL DEFAULT 0
); 

greeting grischan

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.