Какой набор типов данных MySQL эквивалентен в схеме Laravel?

#php #mysql #database #laravel #schema

#php #mysql #База данных #laravel #схема

Вопрос:

В схеме Laravel есть команда для перечисления, эквивалентная таблице. Какой набор эквивалентен таблице?

Комментарии:

1. Начиная с версии 5.8, поддерживаются также столбцы set $table-> set(‘flavors’, [‘strawberry’, ‘vanilla’]);

Ответ №1:

Шаг 1. Расширьте классы по умолчанию (добавьте этот код в файл миграции после use разделов):

 class ExtendedBlueprint extends Blueprint {

    /**
     * Create a new set column on the table.
     *
     * @param  string  $column
     * @param  array   $allowed
     * @return IlluminateSupportFluent
     */
    public function set($column, array $allowed)
    {
        return $this->addColumn('set', $column, compact('allowed'));
    }

}


class ExtendedMySqlGrammar extends IlluminateDatabaseSchemaGrammarsMySqlGrammar {

    /**
     * Create the column definition for an set type.
     *
     * @param  IlluminateSupportFluent  $column
     * @return string
     */
    protected function typeSet(IlluminateSupportFluent $column)
    {
        return "set('".implode("', '", $column->allowed)."')";
    }

}
  

Шаг 2.Затем нам нужно изменить классы грамматики и схемы элементов по умолчанию на наши пользовательские:

 // set new grammar class
DB::connection()->setSchemaGrammar(new ExtendedMySqlGrammar());

// get custom schema object
$schema = DB::connection()->getSchemaBuilder();

// bind new blueprint class
$schema->blueprintResolver(function($table, $callback) {
    return new ExtendedBlueprint($table, $callback);
});

// then create tables 
$schema->create('table name', function(ExtendedBlueprint $table)
{
    $table->increments('id');
    $table->text('sentence');
    $table->string('author')->nullable();
    $table->string('source')->nullable();
    $table->set('difficulty', range(1, 10)); // use our new mysql type 
    $table->boolean('enabled')->default(true);
});
  

Этот метод также будет работать после composer update , потому что мы не редактировали никакого кода фреймворка.

Комментарии:

1. При этом я получаю сообщение об ошибке. Argument 1 passed to CreateTableName::{closure}() must be an instance of ExtendedBlueprint, instance of IlluminateDatabaseSchemaBlueprint given Есть мысли? Я изменил Blueprint на ExtendedBlueprint в моем обратном вызове create.

2. Я понял это. Я использовал Schema::create( ... ) вместо $schema-> create( …)

Ответ №2:

На данный момент Laravel Schema Builder не поддерживает набор типов данных для столбцов. Итак, вот альтернативное решение, пока кто-нибудь не добавит этот код в Laravel.

Шаг 1: Создайте таблицу, используйте ENUM вместо SET .

 Schema::create('schools', function($table)
{
    $table->increments('id');
    $table->char('id_number', 6);
    $table->string('school_name');
    $table->enum('level', array('Preschool', 'Kindergarten', 'Primary', 'Secondary'))->index(); // *** fix this
    $table->string('phone');
    $table->string('email');
    $table->string('location');
    $table->smallInteger('city')->unsigned()->index();
    $table->smallInteger('country')->unsigned()->index();
    $table->smallInteger('head_teacher')->unsigned()->index();
    $table->smallInteger('director')->unsigned()->index();
    $table->smallInteger('created_by')->unsigned();
    $table->smallInteger('modified_by')->unsigned();
    $table->timestamps();
});
  

Шаг 2: теперь измените ENUM на SET .

 $table_prefix = DB::getTablePrefix();
DB::statement("ALTER TABLE `" . $table_prefix . "schools` CHANGE `level` `level` SET('Preschool','Kindergarten','Primary','Secondary');");
  

Если у вас есть лучшее решение, пожалуйста, дайте мне знать.

Комментарии:

1. Почему бы просто не добавить таблицу впоследствии (с помощью DB::statement вызова)? Почему вы добавляете его, а затем изменяете?

2. @ajon Хороший вопрос. Я сделал это так, чтобы свести использование DB::statement к минимуму.

Ответ №3:

Метод Романа Назаркина работает почти идеально, однако есть небольшая проблема с префиксами таблиц (которые этот метод не учитывает), однако просто заставить это предложение работать с префиксами таблиц:

 $grammar = DB::connection()->withTablePrefix(new ExtendedMySqlGrammar());
// set new grammar class
DB::connection()->setSchemaGrammar($grammar);

// get custom schema object
$schema = DB::connection()->getSchemaBuilder();

// bind new blueprint class
$schema->blueprintResolver(function($table, $callback) {
    return new ExtendedBlueprint($table, $callback);
});

// then create tables 
$schema->create('table name', function(ExtendedBlueprint $table)
{
    $table->increments('id');
    $table->text('sentence');
    $table->string('author')->nullable();
    $table->string('source')->nullable();
    $table->set('difficulty', range(1, 10)); // use our new mysql type 
    $table->boolean('enabled')->default(true);
});
  

Ответ №4:

Laravel 5.8 и более поздние версии поддерживают набор типов данных при миграции. Для последних версий вам просто нужно использовать set() function:

 // SET equivalent column named flavors
// Allowed values: strawberry , vanilla
$table->set('flavors', ['strawberry', 'vanilla']);
  

Проверьте более подробную информацию в последней документации:

Ответ №5:

Мое простое одноразовое решение, когда вам нужно создать пользовательский столбец без создания дополнительных файлов для описания расширенной грамматики. Здесь я добавляю свой пользовательский тип rsvp_statuses в PostgresGrammar :

     public function up()
    {
        DB::connection()->setSchemaGrammar(new class extends PostgresGrammar {
            protected function typeRsvp_statuses(IlluminateSupportFluent $column)
            {
                return 'rsvp_statuses';
            }
        });

        Schema::create('mytable', function (Blueprint $table) {
            $table->bigIncrements('id');
            //...
            $table->addColumn('rsvp_statuses', 'status');
            $table->timestamps();
        });
    }
  

Ответ №6:

Расширение методов схемы базы данных laravel не слишком сложно. Как писал Роман, вместо расширения вы также можете обновить свой

vendor/laravel/framework/src/Illuminate/Database/Schema/Grammers/MysqlGrammer.php

 /**
 * Create the column definition for an set type.
 *
 * @param  IlluminateSupportFluent  $column
 * @return string
*/
protected function typeSet(Fluent $column){
    return "set('".implode("', '", $column->allowed)."')";
}  

vendor/laravel/framework/src/Illuminate/Database/Schema/Blueprint.php

 /**
     * Create a new set column on the table.
     *
     * @param  string  $column
     * @param  array   $allowed
     * @return IlluminateSupportFluent
    */
    public function set($column, array $allowed){
        return $this->addColumn('set', $column, compact('allowed'));
    }  

После этого завершите работу вашего сервера, нажав Ctrl C. Затем введите php artisan serve для запуска laravel.