From 259a8ca41757137594bb7b4894be05a1fbb1aa3f Mon Sep 17 00:00:00 2001 From: ywisax Date: Tue, 23 Apr 2024 00:59:38 +0800 Subject: [PATCH] Update AbstractSchemaListener.php to adjust more database params DigitalOcean's mysql instance set the default config "sql_require_primary_key=true", it will cause `./bin/console doctrine:schema:update --dump-sql` throw an Exception: ``` In Connection.php line 33: [PDOException (HY000)] SQLSTATE[HY000]: General error: 3750 Unable to create or change a table without a primary key, when the system variable 'sql_require_primary_key' is set. Add a primary key to the table or unset this variable to avoi d this message. Note that tables without a primary key can cause performance problems in row-based replication, so please consult your DBA before changing this setting. Exception trace: at /root/symfony-app/vendor/doctrine/dbal/src/Driver/PDO/Connection.php:33 PDO->exec() at /root/symfony-app/vendor/doctrine/dbal/src/Driver/PDO/Connection.php:33 Doctrine\DBAL\Driver\PDO\Connection->exec() at /root/symfony-app/vendor/doctrine/dbal/src/Driver/Middleware/AbstractConnectionMiddleware.php:46 Doctrine\DBAL\Driver\Middleware\AbstractConnectionMiddleware->exec() at /root/symfony-app/vendor/doctrine/dbal/src/Logging/Connection.php:50 Doctrine\DBAL\Logging\Connection->exec() at /root/symfony-app/vendor/doctrine/dbal/src/Driver/Middleware/AbstractConnectionMiddleware.php:46 Doctrine\DBAL\Driver\Middleware\AbstractConnectionMiddleware->exec() at /root/symfony-app/vendor/symfony/doctrine-bridge/Middleware/Debug/DBAL3/Connection.php:73 Symfony\Bridge\Doctrine\Middleware\Debug\DBAL3\Connection->exec() at /root/symfony-app/vendor/doctrine/dbal/src/Driver/Middleware/AbstractConnectionMiddleware.php:46 Doctrine\DBAL\Driver\Middleware\AbstractConnectionMiddleware->exec() at /root/symfony-app/bundles/DoctrineEnhanceBundle/src/Middleware/LogConnection.php:64 DoctrineEnhanceBundle\Middleware\LogConnection->exec() at /root/symfony-app/vendor/doctrine/dbal/src/Connection.php:1206 Doctrine\DBAL\Connection->executeStatement() at /root/symfony-app/vendor/doctrine/dbal/src/Schema/AbstractSchemaManager.php:1617 Doctrine\DBAL\Schema\AbstractSchemaManager->_execSql() at /root/symfony-app/vendor/doctrine/dbal/src/Schema/AbstractSchemaManager.php:930 Doctrine\DBAL\Schema\AbstractSchemaManager->createTable() at /root/symfony-app/vendor/symfony/doctrine-bridge/SchemaListener/AbstractSchemaListener.php:34 Symfony\Bridge\Doctrine\SchemaListener\AbstractSchemaListener::Symfony\Bridge\Doctrine\SchemaListener\{closure}() at /root/symfony-app/src/Messenger/DoctrineConnection.php:338 App\Messenger\DoctrineConnection->configureSchema() at /root/symfony-app/vendor/symfony/doctrine-messenger/Transport/DoctrineTransport.php:89 Symfony\Component\Messenger\Bridge\Doctrine\Transport\DoctrineTransport->configureSchema() at /root/symfony-app/vendor/symfony/doctrine-bridge/SchemaListener/MessengerTransportDoctrineSchemaListener.php:43 Symfony\Bridge\Doctrine\SchemaListener\MessengerTransportDoctrineSchemaListener->postGenerateSchema() at /root/symfony-app/vendor/symfony/doctrine-bridge/ContainerAwareEventManager.php:63 Symfony\Bridge\Doctrine\ContainerAwareEventManager->dispatchEvent() at /root/symfony-app/vendor/doctrine/orm/src/Tools/SchemaTool.php:421 Doctrine\ORM\Tools\SchemaTool->getSchemaFromMetadata() at /root/symfony-app/vendor/doctrine/orm/src/Tools/SchemaTool.php:980 Doctrine\ORM\Tools\SchemaTool->getUpdateSchemaSql() at /root/symfony-app/vendor/doctrine/orm/src/Tools/Console/Command/SchemaTool/UpdateCommand.php:92 Doctrine\ORM\Tools\Console\Command\SchemaTool\UpdateCommand->executeSchemaCommand() at /root/symfony-app/vendor/doctrine/orm/src/Tools/Console/Command/SchemaTool/AbstractCommand.php:44 Doctrine\ORM\Tools\Console\Command\SchemaTool\AbstractCommand->doExecute() at /root/symfony-app/vendor/doctrine/orm/src/Tools/Console/CommandCompatibility.php:32 Doctrine\ORM\Tools\Console\Command\SchemaTool\AbstractCommand->execute() at /root/symfony-app/vendor/symfony/console/Command/Command.php:326 Symfony\Component\Console\Command\Command->run() at /root/symfony-app/vendor/symfony/console/Application.php:1096 Symfony\Component\Console\Application->doRunCommand() at /root/symfony-app/vendor/symfony/framework-bundle/Console/Application.php:126 Symfony\Bundle\FrameworkBundle\Console\Application->doRunCommand() at /root/symfony-app/vendor/symfony/console/Application.php:324 Symfony\Component\Console\Application->doRun() at /root/symfony-app/vendor/symfony/framework-bundle/Console/Application.php:80 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /root/symfony-app/vendor/symfony/console/Application.php:175 Symfony\Component\Console\Application->run() at /root/symfony-app/vendor/symfony/runtime/Runner/Symfony/ConsoleApplicationRunner.php:49 Symfony\Component\Runtime\Runner\Symfony\ConsoleApplicationRunner->run() at /root/symfony-app/vendor/autoload_runtime.php:29 require_once() at /root/symfony-app/bin/console:14 ``` This commit will change the code style in `getIsSameDatabaseChecker()`, use doctrine SchemaManager to create/drop the temp table, make it work on most case database instances. --- .../SchemaListener/AbstractSchemaListener.php | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Bridge/Doctrine/SchemaListener/AbstractSchemaListener.php b/src/Symfony/Bridge/Doctrine/SchemaListener/AbstractSchemaListener.php index 04907ee9a78bd..7d286d782cc62 100644 --- a/src/Symfony/Bridge/Doctrine/SchemaListener/AbstractSchemaListener.php +++ b/src/Symfony/Bridge/Doctrine/SchemaListener/AbstractSchemaListener.php @@ -13,6 +13,8 @@ use Doctrine\DBAL\Connection; use Doctrine\DBAL\Exception\TableNotFoundException; +use Doctrine\DBAL\Schema\Table; +use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Tools\Event\GenerateSchemaEventArgs; abstract class AbstractSchemaListener @@ -22,8 +24,16 @@ abstract public function postGenerateSchema(GenerateSchemaEventArgs $event): voi protected function getIsSameDatabaseChecker(Connection $connection): \Closure { return static function (\Closure $exec) use ($connection): bool { + $schemaManager = $connection->createSchemaManager(); + $checkTable = 'schema_subscriber_check_'.bin2hex(random_bytes(7)); - $connection->executeStatement(sprintf('CREATE TABLE %s (id INTEGER NOT NULL)', $checkTable)); + $table = new Table($checkTable); + $table->addColumn('id', Types::INTEGER) + ->setAutoincrement(true) + ->setNotnull(true); + $table->setPrimaryKey(['id']); + + $schemaManager->createTable($table); try { $exec(sprintf('DROP TABLE %s', $checkTable)); @@ -32,7 +42,7 @@ protected function getIsSameDatabaseChecker(Connection $connection): \Closure } try { - $connection->executeStatement(sprintf('DROP TABLE %s', $checkTable)); + $schemaManager->dropTable($checkTable); return false; } catch (TableNotFoundException) {