Este tutorial destina-se a ser uma introdução ao trabalho com o PyMongoArrow. O tutorial pressupõe que o leitor esteja familiarizado com os conceitos básicos de PyMongo e MongoDB.
Instalar o PyMongoArrow
Dica
Compatibilidade
Para obter informações sobre compatibilidade com o PyMongo, PyArrow e seu sistema operacional, consulte a página Compatibilidade.
Você pode instalar o PyMongoArow de três maneiras:
Pip
Conda
Da fonte
Instalar com Pip
Recomendamos usar o pip para instalar o PyMongoArrow em todas as plataformas. PyMongoArrow está disponível no PyPI.
python -m pip install pymongoarrow
Para obter uma versão específica do PyMongo:
python -m pip install pymongoarrow==1.4.0
Para atualizar usando pip:
python -m pip install --upgrade pymongoarrow
Importante
Se a instalação falhar devido a um erro, como ValueError: Could
not find "libbson-1.0" library , isso significa que pip não conseguiu encontrar um rolete adequado para sua plataforma. Recomendamos primeiro garantir que você tenha o pip >= 20.3 instalado. Para atualizar o pip , execute o seguinte comando de shell:
$ python -m pip install --upgrade pip
Você pode então tentar reinstalar o pymongoarrow.
Atualmente, distribuímos discos para macOS, Windows e Linux em arquiteturas x86_64.
Para testar sua instalação, execute o seguinte código na shell do Python. Se o PyMongoArrow estiver instalado corretamente, você não verá erros ou exceções.
import pymongoarrow as pma
Instalar com Conda
O PyMongoArrow está disponível para usuários do conda executando o seguinte comando de shell:
$ conda install --channel conda-forge pymongoarrow
Para testar sua instalação, execute o seguinte código na shell do Python. Se o PyMongoArrow estiver instalado corretamente, você não verá erros ou exceções.
import pymongoarrow as pma
Instalar da origem
Se você não puder usar as opções acima para instalar o pymongoarrow em seu sistema, você poderá instalar a partir da origem. Para saber como, consulte o Guia de Contribuição.
Dependencies
A instalação a partir da origem no Linux requer as seguintes dependências:
GCC versão 12 ou posterior
CCriar
pacote-config
Para usar o PyMongoArrow com um recurso do PyMongo que exige uma dependência opcional, você deve definir a dependência como uma opção ao instalar o PyMongo.
Observação
Para saber mais sobre as dependências opcionais do PyMongo, consulte Dependências na documentação do PyMongo.
Por exemplo, para usar o PyMongoArrow com o Client-Side Field Level Encryption, é necessário instalar o PyMongo com a opção encryption , além de instalar o PyMongoArrow:
python -m pip install 'pymongo[encryption]' pymongoarrow
Os aplicativos que usam APIs PyMongoArrow que retornam conjuntos de resultados de consulta como instâncias pandas.DataFrame , como ~pymongoarrow.api.find_pandas_all(), também devem ter pandas instalado:
python -m pip install pandas
Para testar sua instalação, execute o seguinte código na shell do Python. Se o PyMongoArrow estiver instalado corretamente, você não verá erros ou exceções.
import pymongoarrow as pma
Instale o MongoDB
Este tutorial pressupõe que uma instância MongoDB esteja sendo executada no host e na porta padrão. Depois de baixar e instalar o MongoDB, você pode iniciá-lo conforme mostrado no exemplo de código a seguir:
$ mongod
Inserir dados de amostra
Execute o seguinte código para inserir dados de amostra no seu cluster:
from datetime import datetime from pymongo import MongoClient client = MongoClient() client.db.data.insert_many([ {'_id': 1, 'amount': 21, 'last_updated': datetime(2020, 12, 10, 1, 3, 1), 'account': {'name': 'Customer1', 'account_number': 1}, 'txns': ['A']}, {'_id': 2, 'amount': 16, 'last_updated': datetime(2020, 7, 23, 6, 7, 11), 'account': {'name': 'Customer2', 'account_number': 2}, 'txns': ['A', 'B']}, {'_id': 3, 'amount': 3, 'last_updated': datetime(2021, 3, 10, 18, 43, 9), 'account': {'name': 'Customer3', 'account_number': 3}, 'txns': ['A', 'B', 'C']}, {'_id': 4, 'amount': 0, 'last_updated': datetime(2021, 2, 25, 3, 50, 31), 'account': {'name': 'Customer4', 'account_number': 4}, 'txns': ['A', 'B', 'C', 'D']}])
Definir o esquema
O PyMongoArrow depende de um esquema de dados para organizar conjuntos de resultados de query em formato tabular. If you don't provide this schema, PyMongoArrow infers one from the data. Você pode definir o esquema criando um objeto Schema e mapeando os nomes dos campos para especificadores de tipo, conforme mostrado no exemplo a seguir:
from pymongoarrow.api import Schema schema = Schema({'_id': int, 'amount': float, 'last_updated': datetime})
O MongoDB usa documentos incorporados para representar dados aninhados. O PyMongoArrow oferece suporte de primeira classe para estes documentos:
schema = Schema({'_id': int, 'amount': float, 'account': { 'name': str, 'account_number': int}})
O PyMongoArrow também suporta listas e listas aninhadas:
from pyarrow import list_, string schema = Schema({'txns': list_(string())}) polars_df = client.db.data.find_polars_all({'amount': {'$gt': 0}}, schema=schema)
Dica
O PyMongoArrow inclui vários identificadores de tipo permitidos para cada tipo de BSON suportado. Para uma lista completa destes tipos de dados e seus identificadores de tipo associados, consulte Tipos de dados do.
Encontrar operações
O seguinte exemplo de código mostra como carregar todos os registros que têm um valor diferente de zero para o campo amount como um objeto pandas.DataFrame :
df = client.db.data.find_pandas_all({'amount': {'$gt': 0}}, schema=schema)
Você também pode carregar o mesmo conjunto de resultados que uma instância do pyarrow.Table :
arrow_table = client.db.data.find_arrow_all({'amount': {'$gt': 0}}, schema=schema)
Ou como uma instância polars.DataFrame :
df = client.db.data.find_polars_all({'amount': {'$gt': 0}}, schema=schema)
Ou como um objeto NumPy arrays :
ndarrays = client.db.data.find_numpy_all({'amount': {'$gt': 0}}, schema=schema)
Ao usar o NumPy, o valor retornado é um dicionário onde as chaves são nomes de campos e os valores são as instâncias numpy.ndarray correspondentes.
Observação
Em todos os exemplos anteriores, você pode omitir o esquema como mostrado no exemplo a seguir:
arrow_table = client.db.data.find_arrow_all({'amount': {'$gt': 0}})
Se você omitir o esquema, o PyMongoArrow tentará aplicar automaticamente um esquema com base nos dados contidos no primeiro lote.
Operações agregadas
A execução de uma operação agregada é semelhante à execução de uma operação de busca, mas é necessária uma sequência de operações para ser executada.
O seguinte é um exemplo simples do método aggregate_pandas_all() que gera um novo dataframe no qual todos os valores _id são agrupados e seus valores amount somados:
df = client.db.data.aggregate_pandas_all([{'$group': {'_id': None, 'total_amount': { '$sum': '$amount' }}}])
Você também pode executar operações agregadas em documentos incorporados. O exemplo a seguir desenrola os valores no campo txn aninhado, conta o número de cada valor e retorna os resultados como uma lista de objetos NumPy ndarray , classificados em ordem decrescente:
pipeline = [{'$unwind': '$txns'}, {'$group': {'_id': '$txns', 'count': {'$sum': 1}}}, {'$sort': {"count": -1}}] ndarrays = client.db.data.aggregate_numpy_all(pipeline)
Dica
Para obter mais informações sobre pipelines de agregação, consulte a documentação doMongoDB Server .
Escrevendo no MongoDB
Você pode utilizar o método write() para gravar objetos dos seguintes tipos no MongoDB:
Seta
TablePandas
DataFrameNumPy
ndarrayÁries
DataFrame
from pymongoarrow.api import write from pymongo import MongoClient coll = MongoClient().db.my_collection write(coll, df) write(coll, arrow_table) write(coll, ndarrays)
Observação
As matrizes NumPy são especificadas como dict[str, ndarray].
Ignore Empty Values
O método write() aceita opcionalmente um parâmetro booleano exclude_none. Se você definir este parâmetro como True, o driver não gravará valores vazios no banco de banco de dados. Se você definir esse parâmetro como False ou deixá-lo em branco, o driver gravará None para cada campo vazio.
O código no exemplo a seguir escreve uma seta Table para o MongoDB duas vezes. Um dos valores no campo 'b' está definido como None.
A primeira chamada para o método write() omite o parâmetro exclude_none, então o padrão é False. Todos os valores em Table, incluindo None, são gravados no banco de banco de dados. A segunda chamada para o método write() define exclude_none como True, portanto, o valor vazio no campo 'b' é ignorado.
data_a = [1, 2, 3] data_b = [1, None, 3] data = Table.from_pydict( { "a": data_a, "b": data_b, }, ) coll.drop() write(coll, data) col_data = list(coll.find({})) coll.drop() write(coll, data, exclude_none=True) col_data_exclude_none = list(coll.find({})) print(col_data) print(col_data_exclude_none)
{'_id': ObjectId('...'), 'a': 1, 'b': 1} {'_id': ObjectId('...'), 'a': 2, 'b': None} {'_id': ObjectId('...'), 'a': 3, 'b': 3} {'_id': ObjectId('...'), 'a': 1, 'b': 1} {'_id': ObjectId('...'), 'a': 2} {'_id': ObjectId('...'), 'a': 3, 'b': 3}
Escrevendo para outros formatos
Depois que os conjuntos de resultados forem carregados, você poderá escrevê-los em qualquer formato suportado pelo pacote.
Por exemplo, para gravar a tabela referenciada pela variável arrow_table em um arquivo Parquet denominado example.parquet , execute o seguinte código:
import pyarrow.parquet as pq pq.write_table(arrow_table, 'example.parquet')
O Pandas também suporta a gravação de instâncias do DataFrame em uma variedade de formatos, incluindo CSV e alta definição. Para escrever o período de dados referenciado pela variável df em um arquivo CSV denominado out.csv, execute o seguinte código:
df.to_csv('out.csv', index=False)
A Polars API é uma mistura dos dois exemplos anteriores:
import polars as pl df = pl.DataFrame({"foo": [1, 2, 3, 4, 5]}) df.write_parquet('example.parquet')
Observação
Os dados aninhados são suportados para operações de leitura e escrita em parquet, mas não são bem suportados pelo Arrow ou Pandas para operações de leitura e escrita CSV.
Estendendo o PyMongo
O módulo pymongoarrow.monkey fornece uma interface para corrigir o PyMongo e adicionar a funcionalidade do PyMongoArrow diretamente às instâncias Collection :
from pymongoarrow.monkey import patch_all patch_all()
Após executar o método monkey.patch_all() , as novas instâncias da classe Collection conterão as APIs do PyMongoArrow-- por exemplo, o método pymongoarrow.api.find_pandas_all() .
Observação
Você também pode usar qualquer uma das APIs do PyMongoArrow importando-as do módulo pymongoarrow.api . Se fizer isso, você deverá passar a instância do Collection na qual a operação deve ser executada como o primeiro argumento ao chamar o método de API.
Solução de problemas
Por que obtenho um undefined symbol erro ao instalar o PyMongoArrow a partir do código-fonte?
O PyMongoArrow gera esse erro quando a versão GCC 12 ou posterior não está instalada em seu ambiente Linux. Se você enfrentar esse erro, verifique se você tem o GCC versão 12 ou posterior instalado.
Por que ModuleNotFoundError: No module named 'polars' obtenho ao usar o PyMongoArrow?
O PyMongoArrow gera esse erro quando um aplicativo tenta usar uma API do PyMongoArow que retorna conjuntos de resultados da query como uma instância do polars.DataFrame sem ter o polars instalado no ambiente do Python. Como o polars não é uma dependência direta do PyMongoArrow, ele não é instalado automaticamente quando você instala o pymongoarrow. Você deve instalar o polars separadamente com o seguinte comando de shell:
python -m pip install polars