Esta página foi traduzida pela API Cloud Translation.
Switch to English

Como importar e exportar recursos FHIR com o Cloud Storage

Nesta página, explicamos como exportar e importar recursos do FHIR para e do Cloud Storage usando os métodos projects.locations.datasets.fhirStores.import e projects.locations.datasets.fhirStores.export.

Dependendo do formato dos dados do FHIR, para carregar dados em um armazenamento FHIR, use o método projects.locations.datasets.fhirStores.import ou projects.locations.datasets.fhirStores.fhir.executeBundle. Para orientações sobre como escolher um método, consulte Importação do FHIR.

Como definir permissões do Cloud Storage

Antes de exportar e importar recursos do FHIR de e para o Cloud Storage, é preciso conceder permissões adicionais à conta de serviço Agente de serviço do Cloud Healthcare. Para mais informações, consulte Permissões do Cloud Storage para armazenamento FHIR.

Como gerar dados simulados de pacientes para DSTU2 ou STU3

O Synthea™ é um simulador para gerar dados de população de pacientes. Se você não estiver usando o Synthea, pule para Como importar recursos para o FHIR ou Como exportar recursos do FHIR.

Por padrão, os dados do Synthea™ gerados usam a representação FHIR R4 JSON para os recursos.

Só é possível importar dados na versão que seu armazenamento FHIR está configurado para aceitar. Para gerar dados do FHIR STU3 ou FHIR DSTU2 do Synthea™ para que você possa importá-los para um armazenamento FHIR STU3 ou DSTU2, siga estas etapas:

  1. Clone o repositório de ferramentas do Synthea™ do GitHub:

    git clone https://github.com/synthetichealth/synthea.git
    
  2. Conclua as etapas de instalação.

  3. No diretório synthea, use um editor de texto para abrir o arquivo src/main/resources/synthea.properties e faça as seguintes alterações:

    Para gerar dados do FHIR STU3:

    • Defina todos os valores *.fhir.export e *.fhir_dstu2.export como false.
    • Defina todos os valores *.fhir_stu3.export como "true".

    Para gerar dados do FHIR DSTU2:

    • Defina todos os valores *.fhir.export e *.fhir_stu3.export como false.
    • Defina todos os valores *.fhir_dstu2.export como "true".

    Por exemplo, para gerar dados do FHIR STU3:

    exporter.fhir.export = false
    exporter.fhir_stu3.export = true
    exporter.fhir_dstu2.export = false
    
    exporter.hospital.fhir.export = false
    exporter.hospital.fhir_stu3.export = true
    exporter.hospital.fhir_dstu2.export = false
    
    exporter.practitioner.fhir.export = false
    exporter.practitioner.fhir_stu3.export = true
    exporter.practitioner.fhir_dstu2.export = false
    
  4. Siga as instruções para gerar dados sintéticos de pacientes. Os dados gerados são enviados para synthea/output/fhir_stu3 para o FHIR STU3 ou para o diretório synthea/output/fhir_dstu2 para o FHIR DSTU2.

  5. Copie os dados gerados para um bucket do Cloud Storage para importá-los para um armazenamento FHIR da API Cloud Healthcare. Por exemplo, para copiar os dados para um diretório chamado synthea-data em um bucket existente do Cloud Storage, execute o seguinte comando gsutil cp no diretório synthea:

    gsutil -m cp output/fhir_stu3/* gs://BUCKET/synthea-data
    
  6. Siga as instruções para importar recursos para o FHIR.

Como importar recursos para o FHIR

Ao configurar o corpo da solicitação de importação, você pode definir ContentStructure como um dos valores a seguir.

  • CONTENT_STRUCTURE_UNSPECIFIED
  • BUNDLE: o arquivo de origem contém uma ou mais linhas de JSON delimitado por nova linha (ndjson). Cada linha é um pacote, que contém um ou mais recursos. Se você não especificar ContentStructure, o padrão será BUNDLE.
  • RESOURCE: o arquivo de origem contém uma ou mais linhas de JSON delimitado por nova linha (ndjson). Cada linha é um único recurso.
  • BUNDLE_PRETTY: todo o arquivo de origem é um pacote JSON. O JSON pode abranger várias linhas.
  • RESOURCE_PRETTY: todo o arquivo de origem é um recurso JSON. O JSON pode abranger várias linhas.

Por exemplo, suponha que você esteja importando um arquivo chamado resources.ndjson com o seguinte conteúdo:

{"class":{"code":"IMP","display":"inpatient encounter","system":"http://hl7.org/fhir/v3/ActCode"},"id":"6090e773-3e91-40a7-8fce-1e22f6774c29","reason":[{"text":"The patient had an abnormal heart rate. She was concerned about this."}],"resourceType":"Encounter","status":"finished","subject":{"reference":"Patient/2938bb9e-1f16-429e-8d44-9508ab0e4151"}}
{"class":{"code":"IMP","display":"inpatient encounter","system":"http://hl7.org/fhir/v3/ActCode"},"id":"7101f884-4f02-51b8-9gdf-2f33g7885d30","reason":[{"text":"The patient was experiencing recurrent fevers."}],"resourceType":"Encounter","status":"finished","subject":{"reference":"Patient/3049cc0f-2g27-530f-9e55-0619bc1f5262"}}
{"birthDate":"1970-01-01","gender":"female","id":"2938bb9e-1f16-429e-8d44-9508ab0e4151","name":[{"family":"Smith","given":["Darcy"],"use":"official"}],"resourceType":"Patient"}

O arquivo contém dois recursos do Encounter e um recurso Paciente. Como cada recurso está em uma linha separada, você define ContentStructure como RESOURCE.

Seus dados poderão ser importados incorretamente ou não serão importados se ContentStructure não corresponder ao formato dos dados. Por exemplo, o arquivo de amostra acima não será importado corretamente, a menos que ContentStructure seja definido como RESOURCE na solicitação de importação.

Os exemplos a seguir mostram como importar recursos de um bucket do Cloud Storage para o FHIR.

gcloud

Para importar recursos do FHIR para um armazenamento FHIR, use o comando gcloud healthcare fhir-stores import gcs. Especifique as seguintes informações:

  • O nome do conjunto de dados pai
  • O nome do armazenamento FHIR
  • O local do objeto em um bucket do Cloud Storage. O local dos arquivos no bucket é arbitrário e não precisa aderir exatamente ao formato especificado na amostra a seguir. Ao especificar o local dos recursos do FHIR no Cloud Storage, você pode usar caracteres curinga para importar vários arquivos de um ou mais diretórios. Os seguintes caracteres curinga são suportados:
    • Use * para corresponder a 0 ou mais caracteres que não sejam separadores. Por exemplo, gs://BUCKET/DIRECTORY/Example*.ndjson corresponde a Example.ndjson e Example22.ndjson em DIRECTORY.
    • Use ** para corresponder a 0 ou mais caracteres (incluindo separadores). Precisa ser usado no final de um caminho e sem outros caracteres curinga no caminho. Também pode ser usado com uma extensão de nome de arquivo (como .ndjson), que importa todos os arquivos com a extensão de nome de arquivo no diretório especificado e seus subdiretórios. Por exemplo, gs://BUCKET/DIRECTORY/**.ndjson importa todos os arquivos com a extensão de nome de arquivo .ndjson em DIRECTORY e seus subdiretórios.
    • Use ? para corresponder a um caractere. Por exemplo, gs://BUCKET/DIRECTORY/Example?.ndjson corresponde a Example1.ndjson, mas não corresponde a Example.ndjson nem Example01.ndjson.

A amostra a seguir exibe o comando gcloud healthcare fhir-stores import gcs.

gcloud healthcare fhir-stores import gcs FHIR_STORE_ID \
  --dataset=DATASET_ID \
  --location=LOCATION \
  --gcs-uri=gs://BUCKET/DIRECTORY/FHIR_RESOURCE_NAME.ndjson \
  [--content-structure=CONTENT_STRUCTURE]

A linha de comando exibe o ID da operação e, após a conclusão da operação, done:

Request issued for: [FHIR_STORE_ID]
Waiting for operation [OPERATION_ID] to complete...done.
name: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID

Para ver mais detalhes da operação, execute o comando gcloud healthcare operations describe, fornecendo o OPERATION_ID da resposta:

gcloud healthcare operations describe OPERATION_ID \
  --dataset=DATASET_ID

A resposta inclui done: true.

done: true
metadata:
'@type': type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata
apiMethodName: google.cloud.healthcare.v1.fhir.FhirService.ImportResources
createTime: 'CREATE_TIME'
endTime: 'END_TIME'
name: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID
response:
'@type': type.googleapis.com/google.cloud.healthcare.v1.fhir.rest.ImportResourcesResponse
fhirStore: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID

API

Para importar recursos do FHIR para um armazenamento FHIR, use o método projects.locations.datasets.fhirStores.import.

  • O local dos arquivos no bucket é arbitrário e não precisa aderir exatamente ao formato especificado nas amostras a seguir.
  • Ao especificar o local dos recursos do FHIR no Cloud Storage, você pode usar caracteres curinga para importar vários arquivos de um ou mais diretórios. Os seguintes caracteres curinga são suportados:
    • Use * para corresponder a 0 ou mais caracteres que não sejam separadores. Por exemplo, gs://BUCKET/DIRECTORY/Example*.ndjson corresponde a Example.ndjson e Example22.ndjson em DIRECTORY.
    • Use ** para corresponder a 0 ou mais caracteres (incluindo separadores). Precisa ser usado no final de um caminho e sem outros caracteres curinga no caminho. Também pode ser usado com uma extensão de nome de arquivo (como .ndjson), que importa todos os arquivos com a extensão de nome de arquivo no diretório especificado e seus subdiretórios. Por exemplo, gs://BUCKET/DIRECTORY/**.ndjson importa todos os arquivos com a extensão de nome de arquivo .ndjson em DIRECTORY e seus subdiretórios.
    • Use ? para corresponder a um caractere. Por exemplo, gs://BUCKET/DIRECTORY/Example?.ndjson corresponde a Example1.ndjson, mas não corresponde a Example.ndjson nem Example01.ndjson.

curl

Para importar recursos do FHIR para um armazenamento FHIR, faça uma solicitação POST e especifique as seguintes informações:

  • O nome do conjunto de dados pai
  • O nome do armazenamento FHIR
  • O local do objeto em um bucket do Cloud Storage
  • Um token de acesso

O exemplo a seguir mostra como importar um único arquivo usando uma solicitação POST usando curl.

curl -X POST \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    --data "{
      'contentStructure': 'CONTENT_STRUCTURE',
      'gcsSource': {
        'uri': 'gs://BUCKET/DIRECTORY/FHIR_RESOURCE_FILE'
      }
    }" "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:import"

Se a solicitação for bem-sucedida, o servidor retornará a resposta no formato JSON:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
}

A resposta contém um nome de operação. Para rastrear o status da operação, use o método get de operação:

curl -X GET \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"

Se a solicitação for bem-sucedida, o servidor retornará uma resposta com o status da operação no formato JSON:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1.fhir.FhirService.ImportResources",
    "createTime": "CREATE_TIME",
    "endTime": "END_TIME",
    "logsUrl": "https://console.cloud.google.com/logs/viewer/CLOUD_LOGGING_URL",
    "counter": {
      "success": "SUCCESS_COUNT"
    }
  },
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1.fhir.rest.ImportResourcesResponse",
  }
}

PowerShell

Para importar recursos do FHIR para um armazenamento FHIR, faça uma solicitação POST e especifique as seguintes informações:

  • O nome do conjunto de dados pai
  • O nome do armazenamento FHIR
  • O local do objeto em um bucket do Cloud Storage
  • Um token de acesso

O exemplo a seguir mostra uma solicitação POST usando o Windows PowerShell.

$cred = gcloud auth application-default print-access-token
$headers = @{ Authorization = "Bearer $cred" }

Invoke-WebRequest `
  -Method Post `
  -Headers $headers `
  -ContentType: "application/json; charset=utf-8" `
  -Body "{
    'contentStructure': 'CONTENT_STRUCTURE',
    'gcsSource': {
      'uri': 'gs://BUCKET/DIRECTORY/FHIR_RESOURCE_FILE'
    }
  }" `
  -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:import" | Select-Object -Expand Content

Se a solicitação for bem-sucedida, o servidor retornará a resposta no formato JSON:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
}

A resposta contém um nome de operação. Para rastrear o status da operação, use o método get de operação:

$cred = gcloud auth application-default print-access-token
$headers = @{ Authorization = "Bearer $cred" }

Invoke-WebRequest `
  -Method Get `
  -Headers $headers `
  -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID" | Select-Object -Expand Content

Se a solicitação for bem-sucedida, o servidor retornará uma resposta com o status da operação no formato JSON:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1.fhir.FhirService.ImportResources",
    "createTime": "CREATE_TIME",
    "endTime": "END_TIME",
    "logsUrl": "https://console.cloud.google.com/logs/viewer/CLOUD_LOGGING_URL",
    "counter": {
      "success": "SUCCESS_COUNT"
    }
  },
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1.fhir.rest.ImportResourcesResponse",
  }
}

Go

import (
	"context"
	"fmt"
	"io"
	"time"

	healthcare "google.golang.org/api/healthcare/v1"
)

// importsFHIRResource imports an FHIR resource.
func importFHIRResource(w io.Writer, projectID, location, datasetID, fhirStoreID, gcsURI string) error {
	ctx := context.Background()

	healthcareService, err := healthcare.NewService(ctx)
	if err != nil {
		return fmt.Errorf("healthcare.NewService: %v", err)
	}

	storesService := healthcareService.Projects.Locations.Datasets.FhirStores

	name := fmt.Sprintf("projects/%s/locations/%s/datasets/%s/fhirStores/%s", projectID, location, datasetID, fhirStoreID)
	req := &healthcare.ImportResourcesRequest{
		ContentStructure: "RESOURCE",
		GcsSource: &healthcare.GoogleCloudHealthcareV1FhirGcsSource{
			Uri: gcsURI,
		},
	}

	op, err := storesService.Import(name, req).Do()
	if err != nil {
		return fmt.Errorf("Import: %v", err)
	}

	operationsService := healthcareService.Projects.Locations.Datasets.Operations
	ticker := time.NewTicker(1 * time.Second)
	defer ticker.Stop()
	for {
		select {
		case <-ctx.Done():
			return ctx.Err()
		case <-ticker.C:
			newOp, err := operationsService.Get(op.Name).Do()
			if err != nil {
				return fmt.Errorf("operationsService.Get(%q): %v", op.Name, err)
			}
			if newOp.Done {
				if newOp.Error != nil {
					return fmt.Errorf("import operation %q completed with error: %s", op.Name, newOp.Error.Details)
				}
				return nil
			}
		}
	}
}

Java

import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.healthcare.v1.CloudHealthcare;
import com.google.api.services.healthcare.v1.CloudHealthcare.Projects.Locations.Datasets.FhirStores;
import com.google.api.services.healthcare.v1.CloudHealthcareScopes;
import com.google.api.services.healthcare.v1.model.GoogleCloudHealthcareV1FhirGcsSource;
import com.google.api.services.healthcare.v1.model.ImportResourcesRequest;
import com.google.api.services.healthcare.v1.model.Operation;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.Collections;

public class FhirStoreImport {
  private static final String FHIR_NAME = "projects/%s/locations/%s/datasets/%s/fhirStores/%s";
  private static final JsonFactory JSON_FACTORY = new JacksonFactory();
  private static final NetHttpTransport HTTP_TRANSPORT = new NetHttpTransport();

  public static void fhirStoreImport(String fhirStoreName, String gcsUri) throws IOException {
    // String fhirStoreName =
    //    String.format(
    //        FHIR_NAME, "your-project-id", "your-region-id", "your-dataset-id", "your-fhir-id");
    // String gcsUri = "gs://your-bucket-id/path/to/destination/dir"

    // Initialize the client, which will be used to interact with the service.
    CloudHealthcare client = createClient();

    // Configure where the store should be imported from.
    GoogleCloudHealthcareV1FhirGcsSource gcsSource =
        new GoogleCloudHealthcareV1FhirGcsSource().setUri(gcsUri);
    ImportResourcesRequest importRequest = new ImportResourcesRequest().setGcsSource(gcsSource);

    // Create request and configure any parameters.
    FhirStores.CloudHealthcareImport request =
        client
            .projects()
            .locations()
            .datasets()
            .fhirStores()
            .healthcareImport(fhirStoreName, importRequest);

    // Execute the request, wait for the operation to complete, and process the results.
    try {
      Operation operation = request.execute();
      while (operation.getDone() == null || !operation.getDone()) {
        // Update the status of the operation with another request.
        Thread.sleep(500); // Pause for 500ms between requests.
        operation =
            client
                .projects()
                .locations()
                .datasets()
                .operations()
                .get(operation.getName())
                .execute();
      }
      System.out.println("FHIR store import complete: " + operation.getResponse());
    } catch (Exception ex) {
      System.out.printf("Error during request execution: %s", ex.toString());
      ex.printStackTrace(System.out);
    }
  }

  private static CloudHealthcare createClient() throws IOException {
    // Use Application Default Credentials (ADC) to authenticate the requests
    // For more information see https://cloud.google.com/docs/authentication/production
    GoogleCredentials credential =
        GoogleCredentials.getApplicationDefault()
            .createScoped(Collections.singleton(CloudHealthcareScopes.CLOUD_PLATFORM));

    // Create a HttpRequestInitializer, which will provide a baseline configuration to all requests.
    HttpRequestInitializer requestInitializer =
        request -> {
          new HttpCredentialsAdapter(credential).initialize(request);
          request.setConnectTimeout(60000); // 1 minute connect timeout
          request.setReadTimeout(60000); // 1 minute read timeout
        };

    // Build the client for interacting with the service.
    return new CloudHealthcare.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer)
        .setApplicationName("your-application-name")
        .build();
  }
}

Node.js

const {google} = require('googleapis');
const healthcare = google.healthcare('v1');
const sleep = require('../sleep');

const importFhirResources = async () => {
  const auth = await google.auth.getClient({
    scopes: ['https://www.googleapis.com/auth/cloud-platform'],
  });
  google.options({auth});

  // TODO(developer): uncomment these lines before running the sample
  // const cloudRegion = 'us-central1';
  // const projectId = 'adjective-noun-123';
  // const datasetId = 'my-dataset';
  // const fhirStoreId = 'my-fhir-store';
  // const gcsUri = 'my-bucket/my-directory/*.json'
  const name = `projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}/fhirStores/${fhirStoreId}`;
  const request = {
    name,
    resource: {
      contentStructure: 'RESOURCE',
      gcsSource: {
        uri: `gs://${gcsUri}`,
      },
    },
  };

  const operation = await healthcare.projects.locations.datasets.fhirStores.import(
    request
  );
  const operationName = operation.data.name;

  const operationRequest = {name: operationName};

  // Wait twenty seconds for the LRO to finish.
  await sleep(20000);

  // Check the LRO's status
  const operationStatus = await healthcare.projects.locations.datasets.operations.get(
    operationRequest
  );

  const success = operationStatus.data.metadata.counter.success;

  if (typeof success !== 'undefined') {
    console.log(
      `Import FHIR resources succeeded. ${success} resources imported.`
    );
  } else {
    console.log(
      'Imported FHIR resources failed. Details available in Cloud Logging at the following URL:\n',
      operationStatus.data.metadata.logsUrl
    );
  }
};

importFhirResources();

Python

def import_fhir_resources(project_id, cloud_region, dataset_id, fhir_store_id, gcs_uri):
    """Import resources into the FHIR store by copying them from the
    specified source.
    """
    client = get_client()
    fhir_store_parent = "projects/{}/locations/{}/datasets/{}".format(
        project_id, cloud_region, dataset_id
    )
    fhir_store_name = "{}/fhirStores/{}".format(fhir_store_parent, fhir_store_id)

    body = {
        "contentStructure": "CONTENT_STRUCTURE_UNSPECIFIED",
        "gcsSource": {"uri": "gs://{}".format(gcs_uri)},
    }

    # Escape "import()" method keyword because "import"
    # is a reserved keyword in Python
    request = (
        client.projects()
        .locations()
        .datasets()
        .fhirStores()
        .import_(name=fhir_store_name, body=body)
    )

    response = request.execute()
    print("Imported FHIR resources: {}".format(gcs_uri))

    return response

Como exportar recursos do FHIR

Os exemplos a seguir mostram como exportar recursos do FHIR para um bucket do Cloud Storage. Quando você exporta recursos do FHIR de um armazenamento FHIR, todos os recursos no armazenamento FHIR são exportados.

Durante a exportação, a API Cloud Healthcare cria um arquivo para cada tipo de recurso do armazenamento de FHIR. O nome do arquivo consiste no ID da operação e no tipo de recurso, separado por um sublinhado. Cada arquivo consiste em um JSON delimitado por nova linha, em que cada linha é um recurso de FHIR correspondente ao tipo de recurso no nome do arquivo. Por exemplo, se você exportar vários registros de pacientes, o arquivo de saída será chamado de algo semelhante a 1264567891234567_Patient e conterá uma linha para cada recurso paciente do armazenamento FHIR.

gcloud

Para exportar instâncias do FHIR para um bucket do Cloud Storage, use o comando gcloud healthcare fhir-stores export gcs. Especifique as seguintes informações:

  • O nome do conjunto de dados pai
  • O nome do armazenamento FHIR
  • O bucket ou diretório de destino do Cloud Storage. Grave em um bucket ou diretório do Cloud Storage, em vez de um objeto, porque a API Cloud Healthcare cria um objeto para cada tipo de recurso. Cada objeto consiste em JSON delimitado por nova linha, em que cada linha é um recurso do FHIR. Se você especificar um diretório que não existe, ele será criado.
  • Um dos seguintes valores para a enum writeDisposition:
  • write-empty: exporta dados somente se as tabelas de destino estiverem vazias. Esse é o padrão.
  • write-truncate: apague todos os dados atuais nas tabelas antes de gravar as instâncias.
  • write-append: anexa dados às tabelas existentes.
  • Um campo opcional, type, que exporta apenas um ou mais tipos de recursos do FHIR
  • Um campo opcional, _since, que exporta somente os recursos atualizados após um horário específico, definido como YYYY-MM-DDThh:mm:ss.sss+zz:zz

A amostra a seguir exibe o comando gcloud healthcare fhir-stores export gcs.

gcloud healthcare fhir-stores export gcs FHIR_STORE_ID \
  --dataset=DATASET_ID \
  --location=LOCATION \
  --gcs-uri=gs://BUCKET/DIRECTORY \
  --write-disposition={WRITE_EMPTY|WRITE_TRUNCATE|WRITE_APPEND}

A linha de comando exibe o ID da operação:

Waiting for operation [OPERATION_ID] to complete...done.
name: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID

Para ver o status da operação, execute o comando gcloud healthcare operations describe, fornecendo o OPERATION_ID da resposta:

gcloud healthcare operations describe OPERATION_ID \
  --dataset=DATASET_ID

Depois que o comando for concluído, a resposta incluirá done.

metadata:
'@type': type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata
apiMethodName: google.cloud.healthcare.v1.fhir.FhirService.ExportFhirData
createTime: "CREATE_TIME"
endTime: "END_TIME"
name: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID
response:
'@type': type.googleapis.com/google.cloud.healthcare.v1.fhir.rest.ExportResourcesResponse
fhirStore: projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID
resourceCount: 'RESOURCE_COUNT'

API

Para exportar recursos do FHIR, use o método projects.locations.datasets.fhirStores.export.

  • Grave em um bucket ou diretório do Cloud Storage, em vez de um objeto, porque a API Cloud Healthcare cria um arquivo JSON delimitado por nova linha para cada tipo de recurso. Em cada arquivo JSON, cada linha é um recurso do FHIR.
  • Se o comando especificar um diretório que não existe, o diretório será criado.

curl

Para exportar recursos do FHIR, faça uma solicitação POST e especifique as seguintes informações:

  • O nome do conjunto de dados pai
  • O nome do armazenamento FHIR
  • O bucket de destino do Cloud Storage
  • Um token de acesso
  • Um dos seguintes valores para a enum writeDisposition:
    • write-empty: exporta dados somente se as tabelas de destino estiverem vazias. Esse é o padrão.
    • write-truncate: apague todos os dados atuais nas tabelas antes de gravar as instâncias.
    • write-append: anexa dados às tabelas existentes.
  • Um campo opcional, _type, que exporta apenas um ou mais tipos de recursos do FHIR
  • Um campo opcional, _since, que exporta somente os recursos atualizados após um horário específico, definido como YYYY-MM-DDThh:mm:ss.sss+zz:zz

O exemplo a seguir mostra uma solicitação POST usando curl.

curl -X POST \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    -H "Content-Type: application/json; charset=utf-8" \
    --data "{
      'gcsDestination': {
        'uriPrefix': 'gs://BUCKET/DIRECTORY'
      }
      'writeDisposition': '{WRITE_EMPTY|WRITE_TRUNCATE|WRITE_APPEND}'
    }" "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:export"

Se a solicitação for bem-sucedida, o servidor retornará a resposta no formato JSON:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
}

A resposta contém um nome de operação. Para rastrear o status da operação, use o método get de operação:

curl -X GET \
    -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
    "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"

Se a solicitação for bem-sucedida, o servidor retornará uma resposta com o status da operação no formato JSON:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1.fhir.FhirService.ExportResources",
    "createTime": "CREATE_TIME",
    "endTime": "END_TIME",
    "logsUrl": "https://console.cloud.google.com/logs/viewer/CLOUD_LOGGING_URL",
    "counter": {
      "success": "SUCCESS_COUNT"
    }
  },
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1.fhir.rest.ExportResourcesResponse",
  }
}

PowerShell

Para exportar recursos do FHIR, faça uma solicitação POST e especifique as seguintes informações:

  • O nome do conjunto de dados pai
  • O nome do armazenamento FHIR
  • O bucket ou diretório de destino do Cloud Storage. Grave em um bucket ou diretório do Cloud Storage, em vez de um objeto, porque a API Cloud Healthcare cria um objeto para cada tipo de recurso. Cada objeto consiste em JSON delimitado por nova linha, em que cada linha é um recurso do FHIR.
  • Um token de acesso
  • Um dos seguintes valores para a enum writeDisposition:
    • write-empty: exporta dados somente se as tabelas de destino estiverem vazias. Esse é o padrão.
    • write-truncate: apague todos os dados atuais nas tabelas antes de gravar as instâncias.
    • write-append: anexa dados às tabelas existentes.
  • Um campo opcional, _type, que exporta apenas um ou mais tipos de recursos do FHIR
  • Um campo opcional, _since, que exporta somente os recursos atualizados após um horário específico, definido como YYYY-MM-DDThh:mm:ss.sss+zz:zz

O exemplo a seguir mostra uma solicitação POST usando o Windows PowerShell.

$cred = gcloud auth application-default print-access-token
$headers = @{ Authorization = "Bearer $cred" }

Invoke-WebRequest `
  -Method Post `
  -Headers $headers `
  -ContentType: "application/json; charset=utf-8" `
  -Body "{
    'gcsDestination': {
      'uriPrefix': 'gs://BUCKET/DIRECTORY'
    }
    'writeDisposition': '{WRITE_EMPTY|WRITE_TRUNCATE|WRITE_APPEND}'
  }" `
  -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/fhirStores/FHIR_STORE_ID:export" | Select-Object -Expand Content

Se a solicitação for bem-sucedida, o servidor retornará a resposta no formato JSON:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID"
}

A resposta contém um nome de operação. Para rastrear o status da operação, use o método get de operação:

$cred = gcloud auth application-default print-access-token
$headers = @{ Authorization = "Bearer $cred" }

Invoke-WebRequest `
  -Method Get `
  -Headers $headers `
  -Uri "https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID" | Select-Object -Expand Content

Se a solicitação for bem-sucedida, o servidor retornará uma resposta com o status da operação no formato JSON:

{
  "name": "projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/operations/OPERATION_ID",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1.OperationMetadata",
    "apiMethodName": "google.cloud.healthcare.v1.fhir.FhirService.ExportResources",
    "createTime": "CREATE_TIME",
    "endTime": "END_TIME",
    "logsUrl": "https://console.cloud.google.com/logs/viewer/CLOUD_LOGGING_URL",
    "counter": {
      "success": "SUCCESS_COUNT"
    }
  },
  "done": true,
  "response": {
    "@type": "type.googleapis.com/google.cloud.healthcare.v1.fhir.rest.ExportResourcesResponse",
  }
}

Go

import (
	"context"
	"fmt"
	"io"
	"time"

	healthcare "google.golang.org/api/healthcare/v1"
)

// exportFHIRResource exports the resources in the FHIR store.
func exportFHIRResource(w io.Writer, projectID, location, datasetID, fhirStoreID, gcsURIPrefix string) error {
	ctx := context.Background()

	healthcareService, err := healthcare.NewService(ctx)
	if err != nil {
		return fmt.Errorf("healthcare.NewService: %v", err)
	}

	storesService := healthcareService.Projects.Locations.Datasets.FhirStores

	name := fmt.Sprintf("projects/%s/locations/%s/datasets/%s/fhirStores/%s", projectID, location, datasetID, fhirStoreID)
	req := &healthcare.ExportResourcesRequest{
		GcsDestination: &healthcare.GoogleCloudHealthcareV1FhirGcsDestination{
			UriPrefix: gcsURIPrefix,
		},
	}

	op, err := storesService.Export(name, req).Do()
	if err != nil {
		return fmt.Errorf("Export: %v", err)
	}

	operationsService := healthcareService.Projects.Locations.Datasets.Operations
	ticker := time.NewTicker(1 * time.Second)
	defer ticker.Stop()
	for {
		select {
		case <-ctx.Done():
			return ctx.Err()
		case <-ticker.C:
			newOp, err := operationsService.Get(op.Name).Do()
			if err != nil {
				return fmt.Errorf("operationsService.Get(%q): %v", op.Name, err)
			}
			if newOp.Done {
				if newOp.Error != nil {
					return fmt.Errorf("export operation %q completed with error: %v", op.Name, newOp.Error)
				}
				return nil
			}
		}
	}
}

Java

import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.healthcare.v1.CloudHealthcare;
import com.google.api.services.healthcare.v1.CloudHealthcare.Projects.Locations.Datasets.FhirStores;
import com.google.api.services.healthcare.v1.CloudHealthcareScopes;
import com.google.api.services.healthcare.v1.model.ExportResourcesRequest;
import com.google.api.services.healthcare.v1.model.GoogleCloudHealthcareV1FhirGcsDestination;
import com.google.api.services.healthcare.v1.model.Operation;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import java.io.IOException;
import java.util.Collections;

public class FhirStoreExport {
  private static final String FHIR_NAME = "projects/%s/locations/%s/datasets/%s/fhirStores/%s";
  private static final JsonFactory JSON_FACTORY = new JacksonFactory();
  private static final NetHttpTransport HTTP_TRANSPORT = new NetHttpTransport();

  public static void fhirStoreExport(String fhirStoreName, String gcsUri) throws IOException {
    // String fhirStoreName =
    //    String.format(
    //        FHIR_NAME, "your-project-id", "your-region-id", "your-dataset-id", "your-fhir-id");
    // String gcsUri = "gs://your-bucket-id/path/to/destination/dir"

    // Initialize the client, which will be used to interact with the service.
    CloudHealthcare client = createClient();

    // Configure where the store will be exported too.
    GoogleCloudHealthcareV1FhirGcsDestination gcsDestination =
        new GoogleCloudHealthcareV1FhirGcsDestination().setUriPrefix(gcsUri);
    ExportResourcesRequest exportRequest =
        new ExportResourcesRequest().setGcsDestination(gcsDestination);

    // Create request and configure any parameters.
    FhirStores.Export request =
        client.projects().locations().datasets().fhirStores().export(fhirStoreName, exportRequest);

    // Execute the request, wait for the operation to complete, and process the results.
    try {
      Operation operation = request.execute();
      while (operation.getDone() == null || !operation.getDone()) {
        // Update the status of the operation with another request.
        Thread.sleep(500); // Pause for 500ms between requests.
        operation =
            client
                .projects()
                .locations()
                .datasets()
                .operations()
                .get(operation.getName())
                .execute();
      }
      System.out.println("Fhir store export complete." + operation.getResponse());
    } catch (Exception ex) {
      System.out.printf("Error during request execution: %s", ex.toString());
      ex.printStackTrace(System.out);
    }
  }

  private static CloudHealthcare createClient() throws IOException {
    // Use Application Default Credentials (ADC) to authenticate the requests
    // For more information see https://cloud.google.com/docs/authentication/production
    GoogleCredentials credential =
        GoogleCredentials.getApplicationDefault()
            .createScoped(Collections.singleton(CloudHealthcareScopes.CLOUD_PLATFORM));

    // Create a HttpRequestInitializer, which will provide a baseline configuration to all requests.
    HttpRequestInitializer requestInitializer =
        request -> {
          new HttpCredentialsAdapter(credential).initialize(request);
          request.setConnectTimeout(60000); // 1 minute connect timeout
          request.setReadTimeout(60000); // 1 minute read timeout
        };

    // Build the client for interacting with the service.
    return new CloudHealthcare.Builder(HTTP_TRANSPORT, JSON_FACTORY, requestInitializer)
        .setApplicationName("your-application-name")
        .build();
  }
}

Node.js

const {google} = require('googleapis');
const healthcare = google.healthcare('v1');
const sleep = require('../sleep');

const exportFhirResourcesGcs = async () => {
  const auth = await google.auth.getClient({
    scopes: ['https://www.googleapis.com/auth/cloud-platform'],
  });
  google.options({auth});

  // TODO(developer): uncomment these lines before running the sample
  // const cloudRegion = 'us-central1';
  // const projectId = 'adjective-noun-123';
  // const datasetId = 'my-dataset';
  // const fhirStoreId = 'my-fhir-store';
  // const gcsUri = 'my-bucket/my-directory'
  const name = `projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}/fhirStores/${fhirStoreId}`;
  const request = {
    name,
    resource: {
      gcsDestination: {
        // The destination location in Cloud Storage for the FHIR resources
        uriPrefix: `gs://${gcsUri}`,
      },
    },
  };

  const operation = await healthcare.projects.locations.datasets.fhirStores.export(
    request
  );
  const operationName = operation.data.name;

  // Wait ten seconds for the LRO to finish
  await sleep(10000);

  // Check the LRO's status
  const operationStatus = await healthcare.projects.locations.datasets.operations.get(
    {name: operationName}
  );

  if (typeof operationStatus.data.metadata.counter !== 'undefined') {
    console.log('Exported FHIR resources successfully');
  } else {
    console.log('Export failed');
  }
};

exportFhirResourcesGcs();

Python

def export_fhir_store_gcs(project_id, cloud_region, dataset_id, fhir_store_id, gcs_uri):
    """Export resources to a Google Cloud Storage bucket by copying
    them from the FHIR store."""
    client = get_client()
    fhir_store_parent = "projects/{}/locations/{}/datasets/{}".format(
        project_id, cloud_region, dataset_id
    )
    fhir_store_name = "{}/fhirStores/{}".format(fhir_store_parent, fhir_store_id)

    body = {"gcsDestination": {"uriPrefix": "gs://{}/fhir_export".format(gcs_uri)}}

    request = (
        client.projects()
        .locations()
        .datasets()
        .fhirStores()
        .export(name=fhir_store_name, body=body)
    )

    response = request.execute()
    print("Exported FHIR resources to bucket: gs://{}".format(gcs_uri))

    return response

Solução de problemas de solicitações de importação e exportação do FHIR

Se ocorrerem erros durante uma solicitação de importação ou exportação do FHIR, eles serão registrados no Cloud Logging. Para mais informações, consulte Como visualizar registros de erros no Cloud Logging.

A seguir