mrjgreen/db-sync

RuntimeException table does not have a primary key

njovujsh opened this issue · 18 comments

My Table has a primary key, but when I run The DbSyn, it returns an error table does not have a primary key what can I do.
Thanks in advance

Step 1 This is the first Table
step 1

Step 2 Second Table
step 2
Step 3
step 3

Step 4
step 4
I first tested on localhost for both of them.

There is a lighter library I tried and it works on local host. The only limitation is that I failed to connect to the remote server!. This one looks the most awesome but have so far failed to use it.

Can you post a few lines of the data from the source table?

What happens if you include both columns for syncing?

$columnConfig = new ColumnConfiguration(array('id', 'name'), array());

datasample
Code

code data
The error is of course still there as from the beginning

So the bit of code responsible for deciding the primary key is here: https://github.com/mrjgreen/db-sync/blob/v3/src/Table.php#L100

It's essentially running this query:

SHOW INDEX FROM db_timesheet.test_table WHERE `key_name` = 'PRIMARY'

which should return a result set including the columns: Column_name, Seq_in_index Eg:

Column_name Seq_in_index
Col1 0
Col2 1

We transform this into an array sorted by the Seq_in_index column:

[
    0 => 'Col1',
    1 => 'Col2'
]

If you could post the results of the query:

SHOW INDEX FROM db_timesheet.test_table WHERE `key_name` = 'PRIMARY'

We should be able to figure out what's going wrong here...

Where is the result?

Thanks for the effort Joe, but unless you want me to share the whole credentials which I can, I have not missed any names. In-fact I used the same table name with two simple columns to make sure I get everything right!

src/Table.php line : 98, add this line: $name = str_replace('"', '`', $name);

Hi, I'm trying to use this packet but for some reason the code doesn't return no error but at the same time it doesn't work .
Here is my sample code :

error_reporting(E_ALL);
ini_set('display_errors', 1);

require_once DIR . '/vendor/autoload.php';

use \DbSync\DbSync;
use \DbSync\Transfer\Transfer;
use \DbSync\Hash\ShaHash;
use \DbSync\Table;
use \DbSync\ColumnConfiguration;

$sync = new DbSync(new Transfer(new ShaHash(),1024,8));
//$sync->setLogger(new Symfony\Component\Console\Logger\ConsoleLogger());

$sync->dryRun(false);

$sync->delete(false);

$sourceConnection = new PDO('mysql:host=hostIp;dbname=dbName','dbName','password');
$targetConnection = new PDO('mysql:host=127.0.0.1;dbname=dbName','dbName','password');

$sourceTable = new Table(new \Database\Connection($sourceConnection), 'aliapidemia', 'categories');
$targetTable = new Table(new \Database\Connection($targetConnection), 'aliapidemia', 'categories');

var_dump($sync->sync($targetTable, $sourceTable));

echo "done";

It only prints out "done" and doesn't do anything.
Someone can please advice ? Thanks ! )

I figured out the mistake, if you look at the command source, you'll see diff code:
look some example:

require "vendor/autoload.php";

use Database\Connectors\ConnectionFactory;
use DbSync\DbSync;
use DbSync\Hash\ShaHash;
use DbSync\Table;
use DbSync\Transfer\Transfer;

$sync = new DbSync(new Transfer(new ShaHash()));

$sync->dryRun(false);

$source = createConnection('localhost', 'root', '', 'utf8');
$destination = createConnection('localhost', 'root', '', 'utf8');

$sourceTable = new Table($source, 'database1', 'table-origin');
$targetTable = new Table($destination, 'database2', 'table-destination');

$sync->sync($sourceTable, $targetTable);


function createConnection($host, $user, $password, $charset)
{
    return (new ConnectionFactory())->make([
        'host'      => $host,
        'port'      => 3306,
        'username'  => $user,
        'password'  => $password,
        'charset'   => $charset,
        'collation' => 'utf8_general_ci',
        'driver'    => 'mysql',

        'options' => [
            \PDO::ATTR_ERRMODE               => \PDO::ERRMODE_EXCEPTION,
            \PDO::ATTR_DEFAULT_FETCH_MODE    => \PDO::FETCH_ASSOC,
            \PDO::ATTR_EMULATE_PREPARES      => false,
        ]
    ]);
}

You just have to use ConnectionFactory instead of \PDO