Parte 1·1.4·20 min de leitura

Na Prática: NCBI e Bancos de Dados Biológicos

Uma introdução prática à consulta do NCBI, GenBank, UniProt e PDB — os principais bancos de dados por trás de quase todos os fluxos de trabalho em bioinformática.

NCBIbancos de dadospráticaferramentas

A biologia gera dados em uma escala que requer infraestrutura de armazenamento e recuperação de nível industrial. O sequenciamento de um único genoma humano produz ~200 GB de leituras brutas. Os bancos de dados do NCBI coletivamente contêm petabytes de dados biológicos acumulados ao longo de décadas. Antes de analisar dados biológicos, você precisa saber onde eles vivem e como extraí-los.

Este capítulo é um guia prático dos principais bancos de dados biológicos — o que eles contêm, como acessá-los programaticamente e como eles se relacionam entre si.

O Panorama dos Bancos de Dados Biológicos

Os dados biológicos não são centralizados. São distribuídos em dezenas de bancos de dados especializados, a maioria dos quais faz referências cruzadas entre si:

Banco de DadosConteúdoURL
NCBI / GenBankSequências de DNA/RNA (todos os organismos)ncbi.nlm.nih.gov
RefSeqSequências de referência curadasncbi.nlm.nih.gov/refseq
UniProt / Swiss-ProtSequências de proteínas + anotaçõesuniprot.org
PDBEstruturas 3D de proteínasrcsb.org
EnsemblAnotação do genoma eucariotoensembl.org
SRALeituras de sequenciamento brutasncbi.nlm.nih.gov/sra
GEOConjuntos de dados de expressão gênicancbi.nlm.nih.gov/geo
dbSNPVariantes genéticas humanas conhecidasncbi.nlm.nih.gov/snp
ClinVarAssociações variante-doençancbi.nlm.nih.gov/clinvar
OMIMDoenças genéticasomim.org

O insight fundamental é que esses bancos de dados são interligados. Um gene no Ensembl tem um ID RefSeq. Esse ID RefSeq mapeia para registros de proteínas UniProt. Essas proteínas têm entradas de estrutura no PDB. As variantes naquele gene estão no dbSNP; variantes patogênicas estão no ClinVar. Aprender a navegar essas referências cruzadas é fundamental para a bioinformática.

NCBI Entrez: A Interface Programática

O sistema Entrez do NCBI é o API gateway para a maioria dos bancos de dados do NCBI. A biblioteca Biopython fornece o módulo Entrez como uma interface Python limpa.

Configuração

python
from Bio import Entrez, SeqIO

# Obrigatório pelo NCBI — eles usam isso para entrar em contato se suas consultas causarem problemas
Entrez.email = "seu@email.com"
Limites de taxa da API

Sem uma chave de API, o NCBI permite 3 requisições/segundo. Com uma chave de API gratuita (disponível no NCBI), você obtém 10 requisições/segundo. Sempre adicione delays entre requisições em loops:

python
import time
time.sleep(0.4)  # fique dentro do limite de 3 req/s

Buscando uma Sequência por Número de Acesso

Cada sequência no GenBank/RefSeq tem um número de acesso — um identificador estável. Por exemplo, NM_007294 é o número de acesso RefSeq para o mRNA do BRCA1 humano.

python
from Bio import Entrez, SeqIO

Entrez.email = "seu@email.com"

# Buscar sequência de mRNA do BRCA1
handle = Entrez.efetch(
    db="nucleotide",
    id="NM_007294",
    rettype="gb",       # formato GenBank
    retmode="text"
)

record = SeqIO.read(handle, "genbank")
handle.close()

print(record.id)               # NM_007294.4
print(len(record.seq))         # comprimento da sequência em pb
print(record.description)      # descrição humana
print(record.seq[:100])        # primeiras 100 bases

Pesquisando Registros

A função esearch executa uma busca de texto e retorna uma lista de IDs:

python
handle = Entrez.esearch(
    db="nucleotide",
    term="BRCA1[Gene Name] AND Homo sapiens[Organism] AND mRNA[Filter]",
    retmax=10
)
search_results = Entrez.read(handle)
handle.close()

ids = search_results["IdList"]
print(f"Encontrados {search_results['Count']} registros, buscando {len(ids)}")

A sintaxe de busca do Entrez usa tags de campo entre colchetes. Campos comuns:

  • [Gene Name] — símbolo do gene
  • [Organism] — espécie
  • [Filter] — tipo de registro (mRNA, protein, RefSeq, etc.)
  • [PDAT] — data de publicação (2020/01/01:2024/12/31[PDAT])

Busca em Lote

Para múltiplos registros, use efetch com uma lista de IDs separada por vírgulas:

python
import time

ids = ["NM_007294", "NM_000059", "NM_000546"]  # BRCA1, BRCA2, TP53

handle = Entrez.efetch(
    db="nucleotide",
    id=",".join(ids),
    rettype="fasta",
    retmode="text"
)

records = list(SeqIO.parse(handle, "fasta"))
handle.close()

for rec in records:
    print(f"{rec.id}: {len(rec.seq)} pb")

O Formato GenBank

O formato flat file do GenBank é o formato mais rico para sequências anotadas. Cada registro contém a sequência mais metadados extensos:

LOCUS       NM_007294               7088 bp    mRNA    linear   PRI 01-JAN-2024
DEFINITION  Homo sapiens BRCA1 DNA repair associated (BRCA1), mRNA.
ACCESSION   NM_007294
VERSION     NM_007294.4
KEYWORDS    RefSeq; MANE Select.
SOURCE      Homo sapiens (human)
  ORGANISM  Homo sapiens
            Eukaryota; Metazoa; Chordata; ...
FEATURES             Location/Qualifiers
     source          1..7088
                     /organism="Homo sapiens"
                     /mol_type="mRNA"
                     /chromosome="17"
     gene            1..7088
                     /gene="BRCA1"
     CDS             232..5824
                     /gene="BRCA1"
                     /product="breast cancer type 1 susceptibility protein"
                     /protein_id="NP_009225.1"
ORIGIN
        1 gaattcgatt tctgaataga gatcaagagg ...

Acessando features programaticamente:

python
record = SeqIO.read(handle, "genbank")

for feature in record.features:
    if feature.type == "CDS":
        print(f"Localização CDS: {feature.location}")
        print(f"Gene: {feature.qualifiers.get('gene', ['?'])[0]}")
        print(f"ID da proteína: {feature.qualifiers.get('protein_id', ['?'])[0]}")

        # Extrair a sequência CDS
        cds_seq = feature.extract(record.seq)
        protein = cds_seq.translate(to_stop=True)
        print(f"Comprimento da proteína: {len(protein)} aa")

UniProt: O Banco de Dados de Sequências de Proteínas

Para proteínas, o UniProt é a referência primária. Ele tem duas camadas:

  • Swiss-Prot — curado manualmente, anotações de alta qualidade (~570k entradas)
  • TrEMBL — anotado computacionalmente, muito maior mas de menor confiança (~250M entradas)

Você acessa o UniProt via API REST:

python
import requests

def fetch_uniprot(accession: str) -> dict:
    url = f"https://rest.uniprot.org/uniprotkb/{accession}.json"
    response = requests.get(url)
    response.raise_for_status()
    return response.json()

# Buscar proteína BRCA1 humana
data = fetch_uniprot("P38398")

print(data["primaryAccession"])    # P38398
print(data["uniProtkbId"])         # BRCA1_HUMAN
print(data["organism"]["scientificName"])  # Homo sapiens

# Sequência da proteína
sequence = data["sequence"]["value"]
print(f"Comprimento: {len(sequence)} aa")
print(f"Massa: {data['sequence']['molWeight']} Da")

Pesquisando o UniProt:

python
def search_uniprot(query: str, fields: str = "accession,id,gene_names,length", max_results: int = 10) -> list:
    url = "https://rest.uniprot.org/uniprotkb/search"
    params = {
        "query": query,
        "fields": fields,
        "size": max_results,
        "format": "json"
    }
    response = requests.get(url, params=params)
    response.raise_for_status()
    return response.json()["results"]

results = search_uniprot("BRCA1 AND organism_id:9606 AND reviewed:true")
for entry in results:
    print(entry["primaryAccession"], entry.get("uniProtkbId"))

O PDB: Banco de Dados de Estruturas de Proteínas

O Protein Data Bank (RCSB PDB) armazena estruturas 3D determinadas experimentalmente. Cada entrada tem um ID PDB de 4 caracteres.

python
import requests

def fetch_pdb_info(pdb_id: str) -> dict:
    url = f"https://data.rcsb.org/rest/v1/core/entry/{pdb_id.lower()}"
    response = requests.get(url)
    response.raise_for_status()
    return response.json()

info = fetch_pdb_info("1JM7")  # domínio BRCT do BRCA1
print(info["struct"]["title"])
print(info["rcsb_entry_info"]["resolution_combined"])
print(info["rcsb_entry_info"]["experimental_method"])

Baixando arquivos de estrutura:

python
from Bio.PDB import PDBParser, MMCIFParser
import urllib.request

# Baixar arquivo PDB
pdb_id = "1JM7"
url = f"https://files.rcsb.org/download/{pdb_id}.pdb"
urllib.request.urlretrieve(url, f"{pdb_id}.pdb")

# Parsear estrutura
parser = PDBParser(QUIET=True)
structure = parser.get_structure(pdb_id, f"{pdb_id}.pdb")

for model in structure:
    for chain in model:
        residues = list(chain.get_residues())
        print(f"Cadeia {chain.id}: {len(residues)} resíduos")
Formatos de arquivo PDB

Arquivos PDB vêm em dois formatos: o formato de texto .pdb legado (limitado a ~100k átomos) e o formato mais novo .cif/.mmCIF (sem limite de tamanho). Para complexos grandes (ribossomos, vírus), use mmCIF. O MMCIFParser do Biopython lida com ambos.

Mapeamento de IDs entre Bancos de Dados

Uma tarefa comum em bioinformática é mapear entre IDs de bancos de dados. O UniProt fornece um serviço para isso:

python
def map_ids(ids: list, from_db: str, to_db: str) -> dict:
    url = "https://rest.uniprot.org/idmapping/run"
    response = requests.post(url, data={
        "ids": ",".join(ids),
        "from": from_db,
        "to": to_db
    })
    job_id = response.json()["jobId"]

    # Polling para resultados
    import time
    while True:
        status = requests.get(f"https://rest.uniprot.org/idmapping/status/{job_id}").json()
        if status.get("jobStatus") == "FINISHED":
            break
        time.sleep(1)

    results_url = f"https://rest.uniprot.org/idmapping/results/{job_id}"
    results = requests.get(results_url).json()
    return {r["from"]: r["to"] for r in results["results"]}

# Mapear IDs de proteínas RefSeq para accessions UniProt
mapping = map_ids(["NP_009225.1", "NP_000050.2"], "RefSeq_Protein", "UniProtKB")
print(mapping)

Padrões Práticos

Padrão 1: Gene → Sequência → Anotação

python
from Bio import Entrez, SeqIO
import time

Entrez.email = "seu@email.com"

def get_gene_info(gene_name: str, organism: str = "Homo sapiens") -> dict:
    # 1. Buscar mRNA RefSeq
    handle = Entrez.esearch(
        db="nucleotide",
        term=f"{gene_name}[Gene Name] AND {organism}[Organism] AND RefSeq[Filter] AND mRNA[Filter]"
    )
    ids = Entrez.read(handle)["IdList"]
    handle.close()

    if not ids:
        return {}

    time.sleep(0.4)

    # 2. Buscar o resultado principal
    handle = Entrez.efetch(db="nucleotide", id=ids[0], rettype="gb", retmode="text")
    record = SeqIO.read(handle, "genbank")
    handle.close()

    # 3. Extrair informações relevantes
    cds_features = [f for f in record.features if f.type == "CDS"]
    result = {
        "accession": record.id,
        "length_bp": len(record.seq),
        "cds_count": len(cds_features),
    }

    if cds_features:
        cds = cds_features[0]
        result["protein_id"] = cds.qualifiers.get("protein_id", ["?"])[0]
        result["protein_length"] = len(cds.extract(record.seq).translate(to_stop=True))

    return result

info = get_gene_info("TP53")
print(info)

Padrão 2: Download em Lote de Sequências para Análise

python
def download_sequences(gene_name: str, organism: str, output_file: str, max_seqs: int = 50):
    Entrez.email = "seu@email.com"

    handle = Entrez.esearch(
        db="nucleotide",
        term=f"{gene_name}[Gene Name] AND {organism}[Organism] AND RefSeq[Filter]",
        retmax=max_seqs
    )
    ids = Entrez.read(handle)["IdList"]
    handle.close()

    time.sleep(0.4)

    handle = Entrez.efetch(
        db="nucleotide",
        id=",".join(ids),
        rettype="fasta",
        retmode="text"
    )

    with open(output_file, "w") as f:
        f.write(handle.read())
    handle.close()

    print(f"Baixadas {len(ids)} sequências para {output_file}")

download_sequences("COX1", "Homo sapiens", "cox1_sequences.fasta")

Resumo

Os principais bancos de dados que você usará constantemente:

  • NCBI Entrez — o gateway para sequências, genomas e literatura. O Biopython o encapsula de forma limpa.
  • UniProt — registros canônicos de proteínas. Use a API REST diretamente.
  • RCSB PDB — dados estruturais. O módulo Bio.PDB do Biopython cuida do parsing.

A referência cruzada entre bancos de dados é a habilidade central. Um gene tem um símbolo, um ID RefSeq, um accession UniProt e possivelmente uma estrutura no PDB — e navegar entre eles é uma operação diária em bioinformática.

Checklist de acesso programático

Antes de escrever uma consulta de banco de dados, verifique:

  1. O banco de dados tem uma API REST estável? (A maioria tem)
  2. Existe uma biblioteca Biopython ou Python dedicada? (Economiza semanas de trabalho)
  3. Quais são os limites de taxa? (Sempre adicione delays em loops)
  4. Você precisa de uma chave de API para maior throughput?
  5. Existe uma opção de download em lote para grandes conjuntos de dados? (FTP/S3 é mais rápido que API para >1000 registros)