Keyboard shortcuts

Press ← or → to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Python 적용 대기 쓰기

Python 적용 대기 쓰기(Staged writes)는 편집을 같은 실행의 다음 조회에 반영하는 Beta 모델입니다. Code Repositories에서 라이브 미리보기와 게시 함수 미리보기를 지원하며, 로컬 개발과 VS Code 작업 공간에서는 해당 미리보기를 지원하지 않습니다.

WriteableClient와 커밋 문맥

function 데코레이터에 beta=True와 편집할 모든 객체 및 다대다 링크를 선언합니다. 중첩 호출이 편집하는 대상도 포함해야 합니다.

첫 인수는 생성 OSDK의 WriteableClient입니다. 런타임이 액션의 트랜잭션 문맥을 담아 주입하므로 함수 안에서 새 클라이언트를 생성해서는 안 됩니다. client.ontology.staged_writes()로 컨테이너를 만듭니다.

일반 편집 컨테이너와 같은 객체 및 링크 API를 사용하지만 get_edits 결과를 반환하지 않습니다. 다른 지원 값을 반환할 수 있습니다. 읽기 전에 클라이언트가 대기 편집을 같은 트랜잭션으로 보내므로 검색과 집계가 이전 편집을 포함합니다.

객체 생성과 수정

아래 Employee는 Integer 기본 키 employee_id, first_name과 last_name을 가진 가상 유형입니다.

from functions.api import Integer, function
from ontology_sdk import WriteableClient
from ontology_sdk.ontology.objects import Employee


@function(beta=True, edits=[Employee])
def update_employee_last_name(client: WriteableClient, employee_id: Integer, new_last_name: str) -> Integer:
    staged = client.ontology.staged_writes()
    staged.objects.Employee.edit(employee_id).last_name = new_last_name
    return employee_id


@function(beta=True, edits=[Employee])
def create_employee(client: WriteableClient, employee_id: Integer, first_name: str, last_name: str) -> Integer:
    staged = client.ontology.staged_writes()
    staged.objects.Employee.create(
        employee_id=employee_id,
        first_name=first_name,
        last_name=last_name,
    )
    return employee_id

edit에는 기본 키 대신 로드한 객체도 전달할 수 있습니다. 인터페이스 편집은 지원하지 않습니다.

다음 Ticket은 String 기본 키 ticket_id와 title, status를 가진 가상 유형입니다. UUID로 새 키를 만듭니다.

from uuid import uuid4
from functions.api import function
from ontology_sdk import WriteableClient
from ontology_sdk.ontology.objects import Ticket


@function(beta=True, edits=[Ticket])
def create_ticket(client: WriteableClient, title: str) -> str:
    ticket_id = str(uuid4())
    staged = client.ontology.staged_writes()
    staged.objects.Ticket.create(ticket_id=ticket_id, title=title, status="open")
    return ticket_id

삭제와 링크

삭제는 staged.objects.Ticket.delete(ticket) 또는 staged.objects.Ticket.delete(ticket_id)를 사용합니다. 두 형태는 각각 객체와 기본 키를 사용하는 대안입니다.

다대다 링크는 수정 가능한 객체의 assigned_tickets.add(ticket) 또는 remove(ticket)를 사용합니다. 이 경우 edits에 OntologyLinkType(Employee, "assignedTickets")를 선언합니다. 일대다 관계는 외래 키를 가진 객체의 생성 또는 수정으로 처리합니다.

생성한 값을 다음 질의에서 읽기

다음 함수는 Ticket을 생성한 뒤 open 티켓의 개수를 계산합니다. 같은 WriteableClient를 사용하므로 새 티켓도 집계에 포함됩니다.

from functions.api import Integer, function
from ontology_sdk import WriteableClient
from ontology_sdk.ontology.objects import Ticket


@function(beta=True, edits=[Ticket])
def create_ticket_and_count_open(client: WriteableClient, ticket_id: str, title: str) -> Integer:
    staged = client.ontology.staged_writes()
    staged.objects.Ticket.create(ticket_id=ticket_id, title=title, status="open")
    return client.ontology.objects.Ticket.where(Ticket.object_type.status == "open").count().compute()

이 예제의 개수는 Integer 범위 안의 데이터에 사용합니다. 같은 실행 밖의 다른 사용자에게는 아직 편집이 보이지 않습니다.

중첩 함수 호출

다음 assign_ticket은 기존 티켓의 상태를 open으로 바꾸고 Employee의 다대다 assignedTickets에 연결하는 실제 함수입니다. 로드하지 못한 티켓은 오류로 처리합니다.

from functions.api import Integer, OntologyLinkType, UserFacingError, function
from ontology_sdk import WriteableClient
from ontology_sdk.ontology.objects import Employee, Ticket


@function(beta=True, edits=[Ticket, OntologyLinkType(Employee, "assignedTickets")])
def assign_ticket(client: WriteableClient, employee_id: Integer, ticket_id: str) -> Integer:
    ticket = client.ontology.objects.Ticket.get(ticket_id)
    if ticket is None:
        raise UserFacingError("배정할 티켓을 조회할 수 없습니다.")
    staged = client.ontology.staged_writes()
    staged.objects.Ticket.edit(ticket).status = "open"
    staged.objects.Employee.edit(employee_id).assigned_tickets.add(ticket)
    return 1

이를 먼저 게시하고 소비 SDK에 가져와 생성된 assign_ticket 호출을 준비한 뒤 다음 bulk_assign_tickets를 사용합니다.

from functions.api import Integer, OntologyLinkType, function
from ontology_sdk import WriteableClient
from ontology_sdk.ontology.objects import Employee, Ticket


@function(beta=True, edits=[Ticket, OntologyLinkType(Employee, "assignedTickets")])
def bulk_assign_tickets(client: WriteableClient, employee_id: Integer, ticket_ids: list[str]) -> Integer:
    for ticket_id in ticket_ids:
        client.ontology.queries.assign_ticket(employee_id=employee_id, ticket_id=ticket_id)
    return len(ticket_ids)

같은 실행에서 다른 Python 또는 TSv2 적용 대기 쓰기 함수, AIP Logic과 쿼리를 호출해도 이전에 만든 편집을 읽고 추가 편집을 함께 임시 저장합니다. 반환한 길이는 처리한 요청 수이며 새로 생성된 링크의 고유 개수를 의미하지 않습니다.

성공과 실패의 경계

최상위 함수가 성공하면 중첩 호출의 편집까지 액션 종료 전에 함께 커밋합니다. 예외가 바깥으로 전파되면 전체 대기 편집을 폐기합니다. 이후 재시도는 액션의 재시도 조건을 따르며 무조건 모든 오류를 재시도하지는 않습니다.

가상의 salary 숫자 속성에 대한 다음 예제는 음수 금액을 거부하는 업무 규칙입니다.

from functions.api import Double, Integer, UserFacingError, function
from ontology_sdk import WriteableClient
from ontology_sdk.ontology.objects import Employee


@function(beta=True, edits=[Employee])
def update_employee_with_validation(client: WriteableClient, employee_id: Integer, new_salary: Double) -> Integer:
    if new_salary < 0:
        raise UserFacingError("Salary cannot be negative")
    staged = client.ontology.staged_writes()
    staged.objects.Employee.edit(employee_id).salary = new_salary
    return employee_id

함수 기반 액션에 연결해야 편집을 적용합니다. 외부 API나 웹훅의 변경은 이 온톨로지 롤백 대상과 별개이며, 미리보기에서 외부 요청까지 차단된다고 가정해서는 안 됩니다.