ORM API


레코드 세트



모델에 정의 된 메서드는 레코드 세트에서 실행되며, 그 레코드세트는 self 입니다.


class AModel(models.Model): _name = 'a.model' def a_method(self): # self는 처음부터 끝까지 모든 레코드 사이에 있을 수 있습니다. # database self.do_operation()


레코드 세트를 반복하면 단일 레코드의 새로운 세트("싱글톤")를 얻을 수 있습니다.

파이썬 문자열을 반복하는 것과 같이 단일 문자의 문자열을 생성합니다.


def do_operation(self):
    print self # => a.model(1, 2, 3, 4, 5)
    for record in self:
        print record # => a.model(1), then a.model(2), then a.model(3), ...




필드 엑세스


레코드 세트는 "Active Record" 인터페이스를 제공합니다.

모델 필드는 레코드에서 직접 읽고 쓸 수 있지만 싱글톤(단일 레코드 레코드세트)에서만 가능합니다.

필드의 값을 걸정하면 데이터베이스를 업데이트합니다.


>>> record.name
Example Name
>>> record.company_id.name
Company Name
>>> record.name = "Bob"


여러 레코드에서 필드를 읽거나 쓰려고 하면 오류가 발생합니다.


관계형 필드(Many2one, One2many, Many2many)에 엑세스 하면 필드가 설정되지 않은 경우 비어있는 레코드 세트가 항상 반환됩니다.



주의

필드에 대한 각 할당은 데이터베이스 업데이트를 트리거합니다.
여러 필드를 동시에 설정하거나 여러 레코드의 필드를 동일한 값으로 설정할 때 write()를 사용합니다.

# 3 * len(records) database updates
for record in records:
    record.a = 1
    record.b = 2
    record.c = 3

# len(records) database updates
for record in records:
    record.write({'a': 1, 'b': 2, 'c': 3})

# 1 database update
records.write({'a': 1, 'b': 2, 'c': 3})



레코드 캐시와 프리페칭

Odoo는 레코드 필드에 대한 캐시를 유지 관리하므로 모든 필드 엑세스가 데이터베이스 요청을 발행하는 것은 아닙니다.
이는 성능 저하로 이어질 수 있습니다.
다음 예제에서는 첫번째 명령문에 대해서만 데이터베이스를 쿼리합니다.

record.name             # 첫번째 엑세스는 데이터베이스에서 값을 읽습니다.
record.name             # 두번째 엑세스는 캐시에서 값을 가져옵니다.

한번에 하나의 레코드에서 하나의 필드를 읽지 않으려면 Odoo는 좋은 결과를 얻기 위해 몇 가지 발견 방법에 따라 레코드와 필드를 프리페치합니다.
필드가 주어진 레코드에서 읽혀지면 ORM은 실제로 더 큰 레코드 세트에서 해당 필드를 읽고 나중에 사용하기 위해 반환 된 값을 캐시에 저장합니다.
프리페치된 레코드 세트는 대게 레코드가 반복되는 레코드 세트 입니다.
게다가 모든 간단한 저장 필드 (boolean, integer, float, char, text, date, datetime, selection, many2one)는 모두 가져옵니다.
모델 테이블의 열에 해당하며 동일한 쿼리에서 효율적으로 가져옵니다.

partner가 1000레코드의 레코드세트인 다음 예제를 생각해보십시오.
프리페치가 없으면 루프는 데이터베이스에 대해 2000개의 쿼리를 작성합니다.
프리페칭을 사용하면 하나의 쿼리만 작성됩니다.

for partner in partners:
    print partner.name          # 첫번째 패스 프리페칭 'name' 과 'lang'
                                # (또 다른 필드) 모든 'partners'
    print partner.lang


프리페칭은 2차 레코드에서도 작동합니다. 
관계형 필드를 읽을 때, 그 값(레코드)은 향후 프리페칭 됩니다.
이 2차 레코드 중 하나에 엑세스 하면 동일한 모델의 모든 2차 레코드를 프리페치 합니다.

다음 예제는 partner와 country에 대한 두 개의 쿼리만 생성합니다.

countries = set() for partner in partners: country = partner.country_id # 첫번째 패스는 모든 partners를 프리페치합니다. countries.add(country.name) # 첫번째 패스는 모든 countries를 프리페치합니다.




Set 연산

레코드 세트는 변경 가능하지 않지만 동일한 모델의 세트를 다양한 세트 조작을 사용해 결합하여 새 레코드 세트를 반환 할 수 있습니다.
Set operations는 순서를 보존하지 않습니다.
  • record in set는 record(1-element의 레코드 세트 여야 함)가 set에 있는지 여부를 반환합니다. record not in set는 역 연산입니다.
  • set1 <= set2 와 set1 < set2 에서 set1이 subset인지 set2가 subset인지를 반환합니다. (resp. strict)
  • set1 >= set2set1 > set2 에서 set1이 superset인지 set2가 superset인지를 반환합니다. (resp. strict)
  • set1 | set2는 두 레코드 세트의 합집합을 반환하며, 두 레코드 세트에 합집합인 레코드를 포함하는 새 레코드 세트를 반환합니다.
  • set1 & set2는 두 레코드 세트의 교집합을 반환하며, 두 레코드 세트에 교집합인 레코드만 포함하는 새 레코드 세트를 반환합니다.
  • set1 - set2는 set2에 없는 set1 레코드만 포함하는 새 레코드 세트를 반환합니다.




기타 레코드 세트 연산


레코드 세트는 반복 가능하므로 일반적으로 파이썬 도구를 변환(map(), sorted(), ifilter(), ...)할 때 사용할 수 있지만 
list나 반복자를 반환하거나, 결과에서 메서드를 호출하는 기능을 제거하거나, 설정작업을 사용합니다.

따라서 레코드 세트는 가능한 경우 레코드 세트를 반환하는 다음 작업을 제공합니다.

filtered()
  • 제공된 조건자 함수를 만족하는 레코드만 포함하는 레코드세트를 반환합니다. 속성은 true 또는 false인 필드로 필터링 할 문자열 일 수도 있습니다.

# company가 현재 사용자인 레코드만 보관 records.filtered(lambda r: r.company_id == user.company_id) # partner가 company인 레코드만 보관 records.filtered("partner_id.is_company")



sorted()
  • 제공된 키 함수로 정렬 된 레코드 세트를 반환합니다. 키가 제공되지 않으면 모델의 기본 정렬 순서를 사용하십시오.
# name으로 레코드 정렬
records.sorted(key=lambda r: r.name)


mapped()
  • 제공된 함수를 레코드 세트의 각 레코드에 적용하고 결과가 레코드 세트인 경우 레코드 세트를 반환합니다.
# 세트의 각 레코드에 대해 두 개의 필드를 합산하는 list를 반환합니다.
records.mapped(lambda r: r.field1 + r.field2)

제공된 함수는 필드 값을 가져오는 문자열 일 수 있습니다.

# name 리스트를 반환합니다. records.mapped('name') # partner 레코드 세트를 반환합니다. record.mapped('partner_id') # 모든 partner bank의 합집합을 반환하며 중복 된 값은 제거됩니다. record.mapped('partner_id.bank_ids')



'Coding' 카테고리의 다른 글

ODOO 11 ::: ORM API - Environment  (0) 2018.04.27
rpc  (0) 2018.04.26
HTTP ::: 프로토콜 구조  (0) 2018.04.26
Odoo 11 ::: Snippets Pagination  (0) 2018.04.17
Odoo 11 ::: Fields Type에 대해 알아보자 (3)  (0) 2018.04.10

+ Recent posts