Laravel移行のコードスタイル

みなさん、こんにちは。





プログラミングのキャリアの最初の5年間は社内プロジェクトに取り組み、次の7年間は、最大5人の開発者からなるチームでさまざまなスタートアップに取り組みました。





現在、私は20人以上の開発者とのプロジェクトに数か月取り組んでおり、作業は約30のブランチで同時に実行され、コード開発用の5つの環境(ドラフト、開発、テスト、ホットフィックス、製品)があり、各環境には独自のデータベース(kamitをスタンド/環境にロールアウトする前に、テストロールアウトは別のデータベースを使用して行われます。つまり、5つの環境に10の別のデータベースがあります)。





複数のブランチで開発することは私にとって目新しいことではありません、私はいつもそれをしました。私にとっての発見は、コードのバージョンとデータベーススキーマのバージョンがまったく同期されていないことでした。小さなプロジェクトでは、スキーム全体を削除して全体をロールすることは問題ありません。数分かかります。このプロジェクトでは、シードを使用してスキームを最初からロールするのに1時間かかります。





コードバージョンとデータベーススキーマバージョンを同期する方法には大きな問題があります。





以下に、私が自分で受け入れたルールについて説明します。この災害に対処するのに役立つテクニックとテクニックを共有していただければ幸いです。





免責事項

以下に示すコードは難読化された戦闘コードです。デバッグはしていません。ファイルで変更する必要があるかもしれません。私はあなたとアイデアを共有するだけです。





問題の説明

, , , - -. .





, - , , , , , ? , ?





, , . , , , . , .





.





: " "

, . , migrations, , , .





, .





:





#   
php artisan migrate --path="services/best-team-servise/database/migrations/2021_02_04_240000_alter_data_model_table_add_unique_index.php" --pretend
#  --pretend    SQL      ,  

#    
php artisan migrate:rollback --step=1
#    ,   
      
      



,





php artisan ide-helper:models "Project\Models\DataModel"
      
      



:





php artisan db:seed --class=DataModelSeeder
      
      



? up() down() , , .





, , , .





Builder :





        $conn = (new DataModel())->connection;
        $builder = Schema::connection($conn);
      
      



( ):





        $isExists = $builder->hasColumn(
            'data_model',
            'deleted_at'
        );
      
      



, :





        if (!$isExists) {
            $builder->table(
                'data_model',
                function (Blueprint $table) {
                    $table->softDeletesTz();
                }
            );
        }
      
      



- , - , , , :





        $alias = (new DataModel())->connection;
        $builder = Schema
            ::connection($alias)
            ->getConnection()
            ->getDoctrineSchemaManager();

$existingIndexes = $builder->listTableIndexes('data_model');
      
      



Laravel , :





Blueprint::unique('index_name');
      
      



:





Blueprint::dropUnique('index_name');
      
      



Laravel , , , SQL, Laravel ? , !





SQL, :





DROP TRIGGER IF EXISTS trigger_name
    ON public.data_model;
CREATE TRIGGER trigger_name
    BEFORE INSERT
    ON public.data_model
    FOR EACH ROW
    EXECUTE PROCEDURE public.function_name();
      
      



, :





DROP TRIGGER IF EXISTS trigger_name
    ON public.data_model;
      
      



: " "

, 1000+ . 1000 , .





, 50+ , "" .









, create, alter, , drop.





.





alter_data_model_add_property_column
alter_data_model_alter_property_column_to_text
alter_data_model_alter_property_column_set_default_value
alter_data_model_create_index_on_code_type_columns
alter_data_model_create_unique_index_on_code_column
      
      



, , MVP.





:





#     
php artisan make:migration create_profile_table --create=profile

#     
php artisan make:migration add_confirmed_to_profile --table=profile
      
      



database/migrations , .





: , nullable()

, NOT NULL, , , , .





, .





nullable(), , .





, , - :





            $columns = Schema
            ::connection((new DataModel())->connection)
            ->getConnection()
            ->getDoctrineSchemaManager()
            ->listTableColumns($(new DataModel())->getTable());

            $data = [];
            foreach ($columns as $column) {
                $name = $column->getName();
/* @var array[] $record    */
                $exists = key_exists($name, $record);
                if ($exists) {
                    $data[$name] = $record[$name];
                }
            }

            $isSuccess = DataModel
                ::withTrashed()
                ->updateOrCreate(
                    ['uniqe_index_column' => $data['uniqe_index_column'],],
                    $data
                )->exists;
      
      



: , null

, , , , , .





または、コードでデフォルト値を使用することもできますが、これはハードコードであり、アプリケーションの柔軟性が失われるため、このメソッドは好きではありません。アプリケーションの操作は、環境変数、構成ファイル、またはデータベースレコードのいずれかを介して構成する必要があります。





結論

この一連のルールは確かに絶対的なものではありません。まず、頭をオンにして常識を働かせます。





コメントで話し合いましょう。あなたの経験を共有してください。








All Articles