用于创建连接表的迁移

Posted

技术标签:

【中文标题】用于创建连接表的迁移【英文标题】:Migration for creating join table 【发布时间】:2021-10-06 08:31:53 【问题描述】:

我的 SQL DB 中有一个名为“projects”的表,其中有一列“categories”,它是 php 数组 "['category_1', 'category_2', 'category_3']" 的 varchar(255) 表示,我想做的是把这些将类别放入一个单独的表中,该表将由除了类别名称之外的唯一整数 id 组成,然后使用连接表以多对多关系将其连接到“项目”。

所以这将是一个执行以下操作的迁移:

    创建一个名为“categories_projects”的连接表 创建一个名为“categories”的表,其中仅包含一个唯一的 ID 和类别的标题 在类别中分别插入一行“category_1”、“category_2”、“category_3” 在“projects”表中查找任何现有的行,并根据上面提到的 varchar(255) 字段“category”,在连接表中创建一个将其连接到相应类别的行。 到目前为止我所拥有的:
    <?php
    
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
    
    class CreateCategoriesTable extends Migration
    
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        
            Schema::create('categories', function (Blueprint $table) 
                $table->increments('id');
                $table->unsignedInteger('parent_id')->nullable();
                $table->string('title');
                $table->timestamps();
                $table->softDeletes();
            );
            DB::table('categories')->insert(
                [
                  'title' => 'category_1'
                ], [
                  'title' => 'category_2'
                ], [
                  'title' => 'category_3'
                ], [
                  'title' => 'category_4'
                ], [
                  'title' => 'category_5'
                ]
            );
            Schema::create('categories_projects', function (Blueprint $table) 
                $table->increments('id');
                $table->unsignedInteger('project_id');
                $table->unsignedInteger('category_id');
                $table->timestamps();
                $table->softDeletes();
            );
            // This doesn't work but it's a representation of what I'm trying to do
            // $categories = DB::rawQuery('select * from categories');
            // foreach ($categories as $category) 
            //    $projects = DB::rawQuery('select * from projects where projects.category like %$category['title']');
            //    foreach($projects as $project) 
            //      DB::table(categories_projects)->insert(['project_id' => $project['id'], 'category_id' => $category['id']]);
            //    
            //    
            // 
        

【问题讨论】:

【参考方案1】:

试试这个:

如果主表中的类别名称两边都用单引号括起来(例如 'category_1')

$categories = DB::rawQuery("select * from categories");
foreach ($categories as $category) 
    $projects = DB::rawQuery("select * from projects where category like '%''" . $category["title"] . "''%' ");

    foreach($projects as $project) 
        DB::table('categories_projects')->insert(['project_id' => $project['id'], 'category_id' => $category['id']]);
    


【讨论】:

我应该注意到,评论部分只是我想要做的一个粗略的想法,但 DB::rawQuery 并不是真正以这种方式返回数组的确切方法。【参考方案2】:

这就是我最终的结果,似乎我在提问的过程中回答了我自己的问题,但无论如何:

public function up()
    
        Schema::dropIfExists('categories');
        Schema::create('categories', function (Blueprint $table) 
            $table->increments('id');
            $table->string('title');
            $table->timestamps();
            $table->softDeletes();
        );
        DB::table('categories')->insert([
            ['title' => 'Addition'],
            ['title' => 'Bathrooms'],
            ['title' => 'Commercial'],
            ['title' => 'Community'],
            ['title' => 'Dental'],
            ['title' => 'Design & Construction'],
            ['title' => 'Facade'],
            ['title' => 'Home Design'],
            ['title' => 'Medical'],
            ['title' => 'Multi-Family'],
            ['title' => 'Office'],
            ['title' => 'Renovation'],
            ['title' => 'Residential'],
            ['title' => 'Restaurant'],
            ['title' => 'Retail'],
            ['title' => 'Student Housing']
        ]);
        Schema::create('categories_projects', function (Blueprint $table) 
            $table->increments('id');
            $table->unsignedInteger('project_id');
            $table->unsignedInteger('category_id');
            $table->timestamps();
            $table->softDeletes();
        );
        $categories = DB::table("categories")->get();
        foreach ($categories as $category) 
            $category_id = $category->id;
            $projects = DB::table('projects')->where('categories', 'like', '%'.$category->title.'%')->get();
            $category_proj = [];
            foreach ($projects as $project) 
                $project_id = $project->id;
                $category_proj[] = ['project_id' => $project_id, 'category_id' => $category_id];
            
            DB::table('categories_projects')->insert($category_proj);
        
    

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    
        Schema::dropIfExists('categories_projects');
        Schema::dropIfExists('categories');
    

【讨论】:

以上是关于用于创建连接表的迁移的主要内容,如果未能解决你的问题,请参考以下文章

生成迁移 - 创建连接表

has_and_belongs_to_many 连接表的 Rails 迁移

生成为 Laravel 作业队列创建表的迁移?

运行显式创建表的迁移时未创建 Django 表。

Flyway V 7.8.1 不会迁移它创建 H2 表的第一个脚本

Django 之 文件配置pycharm及django连接数据库创表及表的增删改查