Executando verificação de segurança...
9

Persistência de Dados em Python: Pickle

O que é Persistência de Dados?

Persistência de dados é a capacidade de armazenar informações de forma permanente, permitindo seu acesso posteriormente. É fundamental em diversas áreas, desde aplicativos de celular até machine learning, onde salvar e recuperar dados entre cada execução do programa/processo é essencial.

Um breve exemplo de onde usar persistência na área de dados:

Quando entrei na área de dados, me deparei com a tarefa de desenvolver um RPA. Neste RPA em questão, os resultados do processo no dia anterior influenciariam diretamente no fluxo de trabalho do processo no dia seguinte. Inicialmente, pensei em usar um banco de dados incorporado como SQLite ou planilha Excel para armazenar os dados. No entanto, percebi que precisaria desenvolver e representar o processo a partir de uma classe, ou seja, um objeto em Python. Nesse contexto, a utilização de um banco de dados ou uma planilha tornaria o processo mais complicado e trabalhoso sem a necessidade.

Pickle

Foi então que pesquisei alternativas e descobri a biblioteca pickle, uma solução eficaz e simples para lidar com casos pequenos como este exemplo. O pickle é uma biblioteca Python que permite salvar objetos Python em arquivos. Ele converte os objetos em uma forma serializada, que pode ser armazenada ou transmitida. Depois, os objetos podem ser desserializados, para seu formato original. Desde então, sempre que preciso lidar com situações similares e sem a necessidade de um banco de dados, recorro ao pickle.

Como serializar um objeto:

import pickle

# Definição dos dados a serem serializados
dados = {
    'pessoa': {
        'nome': 'João',
        'idade': 30,
    },
    'itens_compra': ['maçã', 'banana', 'laranja'],
    'total_compra': 25.50
}

# Serializa os dados e os salva em um arquivo 'dados.pickle'
pickle.dump(dados, open('dados.pickle', 'wb'))

Como desserializar um objeto:

import pickle

# Desserializa os dados do arquivo 'dados.pickle' e os carrega de volta para a variável 'dados'
dados = pickle.load(open('dados.pickle', 'rb'))

# Exibe os dados desserializados
print(dados)

E pronto, com duas funções simples da biblioteca, dump() e load(), você fez a persistência do objeto.

Você pode acessar os dois códigos de exemplo através do repositório: https://github.com/danielneresrodrigues/pickle

Carregando publicação patrocinada...
4

Pickle é muito útil para serializar de forma fácil objetos Python. A única advertência que dou é só usar com dados que você confie, senão sua aplicação estará em risco por uma questão de segurança. Na própria página do módulo Python tem um aviso:

Aviso O módulo pickle não é seguro. Selecione apenas dados em que você confia.
É possível construir dados pickle maliciosos que executarão código arbitrário durante a remoção. Nunca retire dados que possam ter vindo de uma fonte não confiável ou que possam ter sido adulterados.
Considere assinar dados com hmac se precisar garantir que eles não foram adulterados.
Formatos de serialização mais seguros, como JSON, podem ser mais apropriados se você estiver processando dados não confiáveis. Veja Comparação com json.

https://docs.python.org/3.12/library/pickle.html

Se for usar JSON, recomendo usar a biblioteca msgspec, pois a implementação dela é muita mais eficiente que a da biblioteca padrão do Python:
https://github.com/jcrist/msgspec

E msgspec ainda serve para os formatos MessagePack, YAML e TOML. Tem validação de schemas também.

O framework web Litestar usa msgspec por padrão e com isso consegue ter performance melhor que o framework FastAPI:
https://docs.litestar.dev/2/benchmarks.html

1

Muito bem colocado, Gustavo!

O pickle deve ser utilizado exclusivamente em ambientes internos e isolados, onde os dados que serão desserializados vieram da mesma fonte, como citado no exemplo do RPA.

3

Muito obrigado pela contribuição e didatica explicação. Em um projeto acabei usando arquivos de configuração que facilmente podem ser trocados pelo pickle e me resolvem varios problemas.
Obrigado por compartilhar.
Obrigado por existir.

2
2

Um exemplo é quando você tem um objeto do Python com referências circulares. Referências circulares são situações em que um objeto se refere a si mesmo ou a uma cadeia de outros objetos que, por sua vez, se referem a ele. Por exemplo, considere uma classe Python com um atributo "amigo" que faz referência a outra instância da mesma classe. Se duas instâncias se tornarem amigas uma da outra, é criada uma referência circular. Isso ocorre porque "pessoa1" é amiga de "pessoa2", e "pessoa2" é amiga de "pessoa1".

class Pessoa:
    def __init__(self, nome, idade):
        self.nome = nome
        self.idade = idade
        self.amigo = None
    
    def definir_amigo(self, amigo):
        self.amigo = amigo

# Criando duas instâncias da classe Pessoa
pessoa1 = Pessoa("Ana", 25)
pessoa2 = Pessoa("Pedro", 30)

# Definindo uma referência circular entre as duas instâncias
pessoa1.definir_amigo(pessoa2)
pessoa2.definir_amigo(pessoa1)
import json

# Tentativa de serializar o objeto para JSON
json_data = json.dumps(pessoa1)

O código resultará na seguinte mensagem "TypeError: Object of type Pessoa is not JSON serializable" porque o JSON não pode lidar com referências circulares. Por outro lado, usar o Pickle para serializar este objeto resolverá o problema, pois ele pode gerenciar referências circulares.

import pickle

# Serializando o objeto usando Pickle
pickle.dump(pessoa1, open('pessoa.pickle', 'wb'))