Estilo de código para migraciones de Laravel

Hola a todos.





Durante los primeros cinco años de mi carrera como programador, trabajé en un proyecto interno, durante los siguientes siete años trabajé en varias startups, con un equipo de máximo cinco desarrolladores.





Ahora he estado trabajando durante un par de meses en un proyecto con más de 20 desarrolladores, el trabajo se lleva a cabo simultáneamente en unas 30 sucursales, hay cinco entornos para el desarrollo de código (borrador, desarrollo, prueba, revisión, prod), cada entorno tiene su propia base de datos (antes de implementar kamit en stand / environment, se realiza una implementación de prueba utilizando una base de datos separada, es decir, tenemos 10 bases de datos separadas para cinco entornos).





Desarrollar en múltiples ramas no es nuevo para mí, siempre lo he hecho. El descubrimiento para mí fue que la versión del código y la versión del esquema de la base de datos no están sincronizadas de ninguna manera. En un proyecto pequeño, no es un problema dejar el esquema completo y rodarlo en su totalidad, toma unos minutos; en este proyecto, rodar un esquema desde cero con siembra toma desde una hora.





Existe un gran problema con la forma de sincronizar la versión del código y la versión del esquema de la base de datos.





A continuación le contaré las reglas que he aceptado para mí y me alegrará que comparta sus técnicas y técnicas que le ayudarán a afrontar este desastre.





Descargo de responsabilidad

El código que se presenta a continuación es un código de combate ofuscado, no lo he depurado, es posible que deba modificarse con un archivo. Solo comparto ideas contigo.





Descripción del problema

, , , - -. .





, - , , , , , ? , ?





, , . , , , . , .





.





: " "

, . , 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

, , , , , .





O puede usar algún valor predeterminado en el código, pero no me gusta este método, porque es un código duro y esto mata la flexibilidad de nuestra aplicación. El funcionamiento de la aplicación debe configurarse mediante variables de entorno, archivos de configuración o registros de la base de datos.





Conclusión

Este conjunto de reglas ciertamente no es absoluto, en primer lugar, damos la vuelta y usamos el sentido común.





Discutamos en los comentarios. Comparta su experiencia.








All Articles