DB 검색 및 교체. 자동화된 종류

데이터베이스 레코드를 변경해야 한다고 상상해 보십시오. 영향을 받는 레코드를 업데이트하는 작업이 할당되었습니다. 단 한 가지 문제가 있습니다. 어떤 테이블이나 얼마나 많은 레코드가 영향을 받는지 알 수 없습니다. 너 뭐하니?

이번 주 언젠가 발생한 실제 시나리오였습니다. 단, 그것은 사악한 코드 라인이 아니었습니다. Laravel 관계에서 사용되는 끔찍한 클래스 이름을 수정할 때였습니다. 내가 무슨 말을 하는지 아시죠? App\Models\User 종류가 데이터베이스 전체에 널려 있습니다.

이 튜토리얼은 Laravel의 내장 마이그레이션 및 DB 클래스를 사용하여 검색 및 교체를 실행하는 방법을 보여줍니다. 수동으로 검색 및 바꾸기를 실행하거나 외부 도구를 사용하지 않아도 됩니다.

마이그레이션 만들기



artisan 콘솔을 사용하여 마이그레이션 파일을 생성합니다.php artisan make:migration search_replace_relationships

로직 검색 및 교체



영향을 받는 테이블과 열을 알 수 없으므로 DB::update()를 실행할 수 없습니다. 대신 다음을 수행해야 합니다.
검색 및 교체할 항목 목록 가져오기
테이블 목록 가져오기
각 테이블의 열 목록 가져오기
중첩된 for 루프 실행
여러 항목을 업데이트하는 경우 교체하려는 각 항목에 대한 추가 루프가 필요합니다.

변경 목록 가져오기



이 경우 관계 모프를 대체합니다. 설명된 대로 모프 맵을 만들 수 있습니다here. 예를 들어 모프 맵은 다음과 같습니다.

Relation::morphMap([
            'user' => User::class,
            'post' => Post::class,
        ]);


그런 다음 다음을 사용하여 모프 맵을 검색할 수 있습니다.

$morphMap = \Illuminate\Database\Eloquent\Relations\Relation::morphMap();


모든 테이블 목록 가져오기



Laravel에서 테이블 이름 검색에 대한 기본 지원을 찾을 수 없습니다. 또는 이 쿼리를 실행하여 데이터베이스 테이블 목록을 검색할 수 있습니다.$tables = \Illuminate\Support\Facades\DB::select('SHOW TABLES'); Inspired by

각 테이블에 대한 열 목록 가져오기



다음은 첫 번째 루프입니다.

foreach ($tables as $table) {
            $tableName = $table->{sprintf('Tables_in_%s',
                \Illuminate\Support\Facades\DB::connection()->getDatabaseName())};
            $columns   = Schema::getColumnListing($tableName);


테이블 이름을 검색하는 첫 번째 쿼리의 결과는 개체 배열을 반환합니다. 각 객체 키는 Tables_in_dbname 입니다. 올바른 키 구문을 사용하여 실제 테이블 이름을 포함하는 값을 가져옵니다.
다음으로 Schema 클래스를 사용하여 여전히 루프에 있는 동안 테이블 이름의 열을 가져옵니다.

중첩 루프 실행



여기에 첫 번째 중첩 루프가 있습니다. 각 테이블에 대해 각 열을 반복하여 변경하려는 텍스트를 찾고 교체를 수행합니다.

foreach ($columns as $column) {
                $columnType = Schema::getColumnType($tableName, $column);
                if ($columnType === 'string') {

Schema::getColumnType 함수를 사용하여 열의 유형을 가져옵니다. 이 경우 모프 유형을 대체하므로 모프 유형의 필드가 일반적으로 문자열이라는 것을 알기 때문입니다. 설정에서 이것이 다른 경우(매우 가능성이 낮음) 이 단계를 완전히 건너뛸 수 있습니다.

바꾸기 실행



마지막으로 검색 및 바꾸기 논리를 실행합니다.

\Illuminate\Support\Facades\DB::table($tableName)->where($column, $value)->update([$column => $key]);


테이블의 인스턴스를 검색한 다음 각 열에서 값을 검색하고 업데이트 기능을 사용하여 바꿉니다.
이에 상응하는 SQL은 다음과 같습니다.UPDATE FROM $tableName where $column = $value SET $column = $key 이 경우 $key는 모프 맵의 첫 번째 항목에 대한 user이고 이 경우 $value는 클래스 이름입니다.

업데이트 방법은 우리가 마이그레이션을 실행하고 있기 때문에 원하는 동작인 eloquent 이벤트를 발생시키지 않는다는 점에 유의하십시오.

모두 함께 가져와.



마이그레이션 업 기능에서 다음으로 끝나야 합니다.

$tables   = \Illuminate\Support\Facades\DB::select('SHOW TABLES');
        $morphMap = \Illuminate\Database\Eloquent\Relations\Relation::morphMap();
        foreach ($tables as $table) {
            $tableName = $table->{sprintf('Tables_in_%s',
                \Illuminate\Support\Facades\DB::connection()->getDatabaseName())};
            $columns   = Schema::getColumnListing($tableName);
            foreach ($columns as $column) {
                $columnType = Schema::getColumnType($tableName, $column);
                if ($columnType === 'string') {
                    foreach ($morphMap as $key => $value) {
                        \Illuminate\Support\Facades\DB::table($tableName)->where($column, $value)->update([$column => $key]);
                    }
                }
            }
        }


마이그레이션은 모든 프레임워크에서 제공하는 가장 강력한 기능 중 하나라고 생각합니다. 마이그레이션 사용 방법을 마스터하면 프로덕션 데이터베이스에 로그인하지 않고도 사소한 것부터 큰 것까지의 데이터베이스 위반을 해결할 수 있습니다.

이 정보가 유용하다고 생각되셨나요? 아래에 댓글을 달아주세요.

사진 제공 Anete Lusina:

좋은 웹페이지 즐겨찾기