Fixed vB v4.2.3 [XF\Db\DuplicateKeyException] on Positive Reputation

vicos

Member
Affected version
v2.0.12 w/Importer 1.0.2
What is the best way to get around this?

[XF\Db\DuplicateKeyException]
MySQL query error [1062]: Duplicate entry 'post-272801-599' for key 'content_type_id_like_user_id'

I see there is a similar post here: https://xenforo.com/community/threads/src-xf-db-abstractstatement-php-error-during-import.139886/

...which says not to not import the blogs. But, I want to make sure it is the same issue before proceeding. This is a 4.5M post DB and import takes hours.

I was importing from vB 4.2.3 with blog and I left all options checked to import. I can live w/o the blog if need be. It died on STEP 20 of 32 Positive Reputation.

Code:
XF\Db\DuplicateKeyException: MySQL query error [1062]: Duplicate entry 'post-272801-599' for key 'content_type_id_like_user_id' src/XF/Db/AbstractStatement.php:212

Generated by: Unknown account Jan 21, 2019 at 5:55 PM

Stack trace

INSERT  INTO `xf_liked_content` (`like_id`, `content_type`, `content_id`, `like_user_id`, `like_date`, `content_user_id`, `is_counted`) VALUES (?, ?, ?, ?, ?, ?, ?)
------------

#0 src/XF/Db/Mysqli/Statement.php(196): XF\Db\AbstractStatement->getException('MySQL query err...', 1062, '23000')
#1 src/XF/Db/Mysqli/Statement.php(78): XF\Db\Mysqli\Statement->getException('MySQL query err...', 1062, '23000')
#2 src/XF/Db/AbstractAdapter.php(79): XF\Db\Mysqli\Statement->execute()
#3 src/XF/Db/AbstractAdapter.php(161): XF\Db\AbstractAdapter->query('INSERT  INTO `x...', Array)
#4 src/XF/Import/Data/EntityEmulator.php(320): XF\Db\AbstractAdapter->insert('xf_liked_conten...', Array)
#5 src/XF/Import/Data/AbstractEmulatedData.php(39): XF\Import\Data\EntityEmulator->insert(54029, Object(XF\Db\Mysqli\Adapter))
#6 src/XF/Import/Data/AbstractData.php(126): XF\Import\Data\AbstractEmulatedData->write(54029)
#7 src/addons/XFI/Import/Importer/vBulletin.php(4032): XF\Import\Data\AbstractData->save(54029)
#8 src/XF/Import/Runner.php(160): XFI\Import\Importer\vBulletin->stepReputation(Object(XF\Import\StepState), Array, 8)
#9 src/XF/Import/Runner.php(74): XF\Import\Runner->runStep('reputation', Object(XF\Import\StepState), 8)
#10 src/XF/Cli/Command/Import.php(66): XF\Import\Runner->run()
#11 src/vendor/symfony/console/Command/Command.php(245): XF\Cli\Command\Import->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#12 src/vendor/symfony/console/Application.php(835): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#13 src/vendor/symfony/console/Application.php(185): Symfony\Component\Console\Application->doRunCommand(Object(XF\Cli\Command\Import), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#14 src/vendor/symfony/console/Application.php(117): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#15 src/XF/Cli/Runner.php(63): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#16 cmd.php(15): XF\Cli\Runner->run()
#17 {main}

Request state

array(1) {
  ["cli"] => string(17) "cmd.php xf:import"
}
 
Last edited:
I think this happens if multiple source users that have given reputation on the same posts do get merged to one target user.

As a workaround I just added a try .. catch in XFI\Import\Importer\vBulletin->stepReputation
 
As a workaround I just added a try .. catch in XFI\Import\Importer\vBulletin->stepReputation
Thanks for the response. Could you share the code change? Otherwise, it will take me a month of Sundays to get it right, especially since it takes hours to get to the point where it breaks.
 
Last edited:
In src/addons/XFI/Import/Importer/vBulletin.php in method stepReputation around line 4116

Replace
PHP:
if ($newId = $import->save($oldId))
{
    $state->imported++;
}

with
PHP:
try
{
    if ($newId = $import->save($oldId))
    {
        $state->imported++;
    }
}
catch (\Exception $e)
{
    // I don't care if a single like fails for whatever reason - just continue
}

You can just continue a running import after applying the change, it should continue where it stopped.
 
Top Bottom