InfoGrab DocsInfoGrab Docs

여러 데이터베이스 객체 업데이트

ActiveRecord에서 단일 쿼리로 여러 데이터베이스 객체를 일괄 업데이트하는 방법과 Gitlab::Database::BulkUpdate 추상화 사용법을 설명합니다.

하나 이상의 칼럼에 새 값을 설정하여 여러 데이터베이스 객체를 업데이트할 수 있습니다. 한 가지 방법은 Relation#update_all 을 사용하는 것입니다: user.issues.open.update_all(due_date: 7.days.from_now) # (1) user.issues.update_all('relative_position = relative_position + 1') # (2) 업데이트를 정적 값(1)이나 계산식(2)으로 표현할 수 없는 경우, 단일 쿼리에서 각 행마다 다른 값으로 여러 행을 업데이트하려면 UPDATE FROM 을 사용하세요. 임시 테이블이나 공통 테이블 표현식(Common Table Expression, CTE)을 만들어 업데이트 소스로 활용합니다: with updates(obj_id, new_title, new_weight) as ( values (1 :: integer, 'Very difficult issue' :: text, 8 :: integer), (2, 'Very easy issue', 1) ) update issues set title = new_title, weight = new_weight from updates where id = obj_id 이 방식은 ActiveRecord나 Arel 로는 표현할 수 없습니다. UpdateManager 가 update from 을 지원하지 않기 때문입니다. 그러나 이러한 종류의 업데이트를 생성하는 데 도움이 되는 추상화 Gitlab::Database::BulkUpdate 를 제공합니다. 이 추상화는 앞의 예제와 같은 쿼리를 생성하며, 바인딩 파라미터를 사용하여 SQL 인젝션을 방지합니다. 사용법 # Gitlab::Database::BulkUpdate 를 사용하려면 다음이 필요합니다: 업데이트할 칼럼 목록. 객체(또는 ID)에서 해당 객체에 설정할 새 값으로의 매핑. 각 객체의 테이블을 결정하는 방법. 예를 들어, object.class.table_name 을 호출하여 테이블을 결정하는 방식으로 앞의 예제 쿼리를 다음과 같이 표현할 수 있습니다: issue_a = Issue.find(..) issue_b = Issue.find(..) # Issues a single query: ::Gitlab::Database::BulkUpdate.execute(%i[title weight], { issue_a => { title: 'Very difficult issue', weight: 8 }, issue_b => { title: 'Very easy issue', weight: 1 } }) 모든 업데이트가 의미 있는 경우, 이기종 객체 집합도 전달할 수 있습니다: issue_a = Issue.find(..) issue_b = Issue.find(..) merge_request = MergeRequest.find(..) # Issues two queries ::Gitlab::Database::BulkUpdate.execute(%i[title], { issue_a