【问题标题】:Unable to create or change a table without a primary key - Laravel DigitalOcean Managed Database无法创建或更改没有主键的表 - Laravel DigitalOcean 托管数据库
【发布时间】:2020-10-06 15:05:13
【问题描述】:

我刚刚使用(托管数据库)将我的应用程序部署到 DigitalOcean,并且在调用 php artisan migrate 时出现以下错误

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 avoid 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. (SQL: create table `sessions` (`id` varchar(255) not null, `user_id` bigint unsigned null, `ip_address` varchar(45) null, `user_agent` text null, `payload` text not null, `last_activity` int not null) default character set utf8mb4 collate 'utf8mb4_unicode_ci')

当 mysql var sql_require_primary_key 设置为 true 时,Laravel 迁移似乎不起作用。

你有什么解决办法吗?

【问题讨论】:

    标签: mysql laravel migration digital-ocean


    【解决方案1】:

    定义了一个简洁的解决方案here。解决方案是添加侦听器以迁移脚本并在执行迁移之前和之后打开和关闭sql_require_primary_key。此解决方案解决了无法修改迁移脚本的问题,例如当它们来自库或 Voyager 等框架时。

    <?php
    
    namespace App\Providers;
    
        use Illuminate\Database\Events\MigrationsStarted;
        use Illuminate\Database\Events\MigrationsEnded;
        use Illuminate\Support\Facades\DB;
        use Illuminate\Support\Facades\Event;
        use Illuminate\Support\ServiceProvider;
        
        class AppServiceProvider extends ServiceProvider {
            /**
             * Register any application services.
             *
             * @return void
             */
            public function register() {
        
                // check this one here https://github.com/laravel/framework/issues/33238#issuecomment-897063577
                Event::listen(MigrationsStarted::class, function (){
                    if (config('databases.allow_disabled_pk')) {
                        DB::statement('SET SESSION sql_require_primary_key=0');
                    }
                });
        
                Event::listen(MigrationsEnded::class, function (){
                    if (config('databases.allow_disabled_pk')) {
                        DB::statement('SET SESSION sql_require_primary_key=1');
                    }
                });
            } 
    // rest of the class 
    
    }
    

    【讨论】:

      【解决方案2】:

      对于更大的sql文件,可以用这个命令(如果你的文件大小

      第一:

      sed  -i '1i SET SQL_REQUIRE_PRIMARY_KEY = 0;' db.sql
      

      第二:

      sed  -i '1i SET @ORIG_SQL_REQUIRE_PRIMARY_KEY = @@SQL_REQUIRE_PRIMARY_KEY;' db.sql
      

      【讨论】:

        【解决方案3】:

        我通过工单联系了 DigitalOcean,询问他们是否要禁用该要求,他们在第二天就这样做了 :)

        所以你可以问他们

        感谢您与我们联系! 我了解您希望禁用托管数据库的主要要求。您的托管数据库 ****** 的主要要求已被禁用

        【讨论】:

          【解决方案4】:

          添加您的第一个迁移:

          \Illuminate\Support\Facades\DB::statement('SET SESSION sql_require_primary_key=0');
          

          内部:Schema::create() 函数。

          【讨论】:

          • 您的建议效果很好,非常感谢!
          【解决方案5】:

          我试图通过使用 WordPress 安装中的 mysqldump 文件导入 DO Managed MySQL 来解决此问题。我发现将其添加到文件顶部确实对我的导入有用。

          SET @ORIG_SQL_REQUIRE_PRIMARY_KEY = @@SQL_REQUIRE_PRIMARY_KEY;
          SET SQL_REQUIRE_PRIMARY_KEY = 0;
          

          然后我使用 JetBrains DataGrip 导入,它没有错误地工作。

          【讨论】:

          • 为什么不在导入前向缺少它们的表添加主键?
          【解决方案6】:

          很遗憾,我们无法更改数字海洋 MySQL 数据库中的 sql_require_primary_key 值。相反,您可以通过添加 primary() 将 id 设置为主键

          【讨论】:

          • 我将它添加到 digitalocean 上的 sql 文件中并且它有效
          【解决方案7】:

          只需添加set sql_require_primary_key = off 像这样

          到您的 SQL 文件。

          【讨论】:

          • 设置 sql_require_primary_key =off;
          • DigitalOcean ManagedDatabases 中不允许此 sis。
          【解决方案8】:

          将此行添加到您的迁移文件中。 $table->increments('aid');

          【讨论】:

            【解决方案9】:

            根据 MySQL 文档中这个系统变量的用途是

            为了避免复制性能问题:“启用此变量有助于避免在表没有主键时可能发生的基于行的复制中的性能问题。”

            恕我直言,您的问题有两种可能的选择;

            • 向此表和迁移中的每个表添加主键,包括临时表。这个更好,我认为这样做更方便,因为每个表都有主键没有缺点。

            创建新表或更改现有表结构的语句是否强制要求表具有primary key

            • 更改您的提供商,因为根据here“我们仅支持 MySQL v8。”

            这里还有bug report

            【讨论】:

              【解决方案10】:

              启用后,sql_require_primary_key 具有以下效果:

              1. 尝试创建没有主键的新表失败并出现错误。这包括 CREATE TABLE ... LIKE。它还包括 CREATE TABLE ... SELECT,除非 CREATE TABLE 部分包含主键定义。
              2. 尝试从现有表中删除主键失败并出现错误,但允许删除主键并在同一 ALTER TABLE 语句中添加主键除外。

              即使表还包含 UNIQUE NOT NULL 索引,删除主键也会失败。

              1. 尝试导入没有主键的表失败并出现错误。

              默认值为 OFF ,但在您的情况下,您需要从 ON 设置 OFF

              IMPORTANT LINK

              HOW TO SET

              【讨论】:

              • @Michal 你觉得这个答案有帮助吗,然后请标记为答案或投赞成票
              猜你喜欢
              • 2021-06-19
              • 1970-01-01
              • 2021-01-17
              • 2019-03-09
              • 1970-01-01
              • 2018-04-30
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多