Um breve conceito prático sobre Engenharia de Dados

 



Um breve conceito prático sobre Engenharia de Dados

Introdução

    A Engenharia de Dados tem se consolidado como uma das áreas centrais dentro do ecossistema de tecnologia da informação, sendo responsável por projetar, construir e manter infraestruturas que possibilitam a coleta, o armazenamento, o processamento e a disponibilização de dados de forma confiável e escalável. Em um cenário cada vez mais orientado por dados, organizações de diferentes setores dependem diretamente dessas estruturas para apoiar processos decisórios, produtos digitais e estratégias de negócio.

    O ecossistema de Engenharia de Dados já foi previamente apresentado, contemplando suas principais camadas e fluxos. No entanto, além da compreensão conceitual do ecossistema, é fundamental conhecer quais ferramentas são utilizadas em cada etapa desse processo e como elas se integram no dia a dia de um engenheiro de dados. Nesse contexto, este módulo tem como foco o estudo das ferramentas Git, SQL e Python, que são amplamente adotadas no mercado e consideradas essenciais para a atuação prática na área de Engenharia de Dados.

    Para ilustrar essa integração de tecnologias, pode-se observar um exemplo comum do cotidiano digital: a busca por um produto em um site de e-commerce, como a Amazon. Ao realizar uma pesquisa por termos como “clean code”, o sistema retorna uma lista de livros relacionados. Essas informações não surgem de forma aleatória; elas estão previamente armazenadas em bancos de dados transacionais, geralmente organizados de forma tabular.


                                                                                                                                Fonte: site de busca da Amazon

    Esses dados, estruturados em tabelas, precisam ser consultados de maneira eficiente. Para isso, utiliza-se a linguagem SQL (Structured Query Language), que permite realizar consultas, filtros e agregações, possibilitando a recuperação das informações necessárias de forma precisa. O SQL é, portanto, uma das principais linguagens para interação com bancos de dados e desempenha um papel central na Engenharia de Dados.

    A linguagem Python, por sua vez, destaca-se por sua versatilidade. No contexto apresentado, ela pode ser utilizada tanto para a construção da aplicação responsável pela exibição dos produtos quanto para a comunicação com o banco de dados, por meio da execução de consultas SQL. Além disso, o Python permite realizar transformações, validações e tratamentos nos dados recuperados, tornando-se uma ferramenta fundamental em diferentes etapas do fluxo de dados.

  Outro aspecto essencial no desenvolvimento de soluções em Engenharia de Dados é o armazenamento e o controle do código-fonte. Os códigos desenvolvidos fazem parte dos ativos da organização e, muitas vezes, são produzidos de forma colaborativa por diferentes profissionais. Nesse cenário, surge a necessidade de ferramentas que possibilitem o versionamento, o armazenamento seguro e o compartilhamento do código. O Git atende a essa necessidade, oferecendo um conjunto de comandos que permitem controlar versões, acompanhar alterações e gerenciar o histórico de desenvolvimento de um projeto. Plataformas como o GitHub complementam esse processo ao facilitar a colaboração entre equipes.

   Além do GitHub, existem outras ferramentas que oferecem controle de versões, como editores colaborativos e ambientes integrados de desenvolvimento. Entretanto, aplicações de Engenharia de Dados costumam ser mais complexas do que documentos simples, pois envolvem múltiplas funcionalidades, diferentes ambientes (desenvolvimento, testes e produção) e fluxos de entrega contínua. Isso torna o versionamento de código um desafio mais significativo e estratégico. A rotina de desenvolvimento de software geralmente envolve etapas como criação, edição, validação, revisão e publicação do código. Quando múltiplos desenvolvedores atuam simultaneamente sobre os mesmos arquivos, podem ocorrer conflitos, tornando o controle de versões indispensável. O versionamento permite responder a questões críticas, como: qual é a versão mais recente do código?, qual versão está em produção? e como resolver conflitos entre alterações?

    Dessa forma, as tecnologias Git, SQL e Python se complementam e formam a base das atividades práticas em Engenharia de Dados. Compreender seus conceitos, aplicações e boas práticas é essencial para o desenvolvimento de soluções robustas, escaláveis e alinhadas às demandas do mercado atual.

Repositórios e Versionamento de Código

    Repositórios de código são estruturas utilizadas para armazenar, organizar e controlar a evolução de projetos de software ao longo do tempo. Eles permitem que alterações sejam registradas, versionadas e recuperadas, garantindo rastreabilidade, colaboração entre equipes e segurança dos ativos de software de uma organização. Ao longo da evolução do desenvolvimento de software, diferentes arquiteturas de versionamento foram criadas, sendo as principais classificadas como sistemas centralizados e sistemas distribuídos (ou descentralizados). Os repositórios são usados também como forma de 'guardar' registros, dados, diagramas, imagens de forma organizada. 

Exemplo Prático: Versionamento Aplicado a um Projeto de E-book


    Para facilitar o entendimento do versionamento com Git, pode-se imaginar um projeto de desenvolvimento de um livro virtual (e-book). Nesse projeto, a equipe é composta por dois escritores e um revisor. O repositório Git pode ser comparado a um gaveteiro, onde cada gaveta representa uma branch com um propósito específico. A gaveta principal, chamada main, contém a versão final do livro disponível para venda nas lojas online. 

    Cada escritor trabalha em sua própria branch de funcionalidade, por exemplo, feature-capitulo-10, onde registra diariamente suas contribuições. Após a conclusão do capítulo, o conteúdo é enviado para a branch develop por meio de um pull request, permitindo que o revisor avalie e aprove o material.

    Somente após a revisão e validação no ambiente de desenvolvimento é que o conteúdo é integrado à branch main. A entrega final do livro, equivalente ao deploy, pode ser automatizada por meio de pipelines de CI/CD, garantindo que a versão final seja publicada automaticamente nas lojas digitais.

Sistemas Centralizados de Versionamento – Subversion (SVN)

    Os sistemas centralizados de versionamento foram os primeiros modelos amplamente adotados pela indústria. Nesse modelo, existe um servidor central, responsável por armazenar todo o histórico do projeto. Os desenvolvedores precisam se conectar a esse servidor para obter o código, realizar alterações e registrar novas versões.

    Um dos exemplos mais conhecidos desse modelo é o Subversion (SVN), criado no início dos anos 2000 como uma evolução do sistema CVS (Concurrent Versions System). O Subversion foi amplamente utilizado em projetos corporativos e acadêmicos, pois introduziu melhorias significativas, como versionamento de diretórios, controle mais robusto de histórico e melhor gerenciamento de conflitos.

    Entretanto, o modelo centralizado apresenta limitações importantes. A dependência constante de um servidor central dificulta o trabalho offline, e falhas no servidor podem impactar diretamente toda a equipe. Além disso, o processo de colaboração tende a ser menos flexível em projetos grandes ou com equipes distribuídas.

Git e o Modelo Descentralizado de Versionamento

    Com o crescimento de projetos de grande escala e da colaboração global, surgiu a necessidade de um modelo mais flexível. Em 2005, Linus Torvalds, criador do kernel Linux, desenvolveu o Git, um sistema de versionamento distribuído. Diferentemente dos sistemas centralizados, no Git cada desenvolvedor possui uma cópia completa do repositório, incluindo todo o histórico de versões. Isso permite que o trabalho seja realizado localmente, sem a necessidade constante de conexão com um servidor. As alterações só precisam ser sincronizadas quando o desenvolvedor decide compartilhá-las.



    Esse modelo descentralizado trouxe benefícios significativos, como maior desempenho, maior segurança contra perda de dados e melhor suporte ao trabalho colaborativo e paralelo.

Plataformas de Gerenciamento de Repositórios Git

    Embora o Git funcione de forma local, projetos colaborativos exigem um repositório central remoto, onde o código possa ser compartilhado, revisado e integrado. Para isso, surgiram diversas plataformas de gerenciamento de repositórios Git, entre as quais destacam-se:

  • GitHub

  • GitLab

  • Bitbucket

  • Azure DevOps (módulo de repositórios)

    Essas plataformas oferecem uma interface gráfica para manipulação dos códigos, além de recursos adicionais como controle de permissões, documentação, versionamento de releases, integração com pipelines de CI/CD e ferramentas de colaboração. Entre elas, o GitHub se consolidou como a plataforma mais popular, especialmente por sua forte adoção pela comunidade open source e pelo mercado corporativo.

GitHub: Contexto e Importância Atual

    O GitHub, lançado em 2008, tornou-se um dos principais pilares do desenvolvimento colaborativo moderno. Ele não apenas hospeda repositórios Git, mas também oferece funcionalidades que ampliam a governança e a qualidade dos projetos. Entre os principais recursos do GitHub, destacam-se:

  • Repositórios remotos centralizados -> Assim você pode trabalhar localmente e salvar as atualizações de seu projeto sem precisar clonar o repositório.

  • Documentação por meio do arquivo README.md -> Dessa Forma, antes de acessar um projeto, o README.md pode servir, além de uma 'capa' para o trabalho, deve conter  informações detalhadas do projeto em questão. A documentação em um repositório geralmente é estruturada no arquivo README.md, utilizando a linguagem Markdown, que permite formatar textos de forma simples e padronizada.

  • Pull requests para revisão de código -> O Pull Request (PR) é um mecanismo fundamental nos fluxos de trabalho baseados em Git. Ele tem como principal objetivo solicitar a integração de alterações realizadas em uma branch para outra, normalmente de uma feature branch para a branch de desenvolvimento (develop) ou para a branch principal (main).  garantindo qualidade, padronização e segurança antes que novas alterações sejam incorporadas ao projeto. No contexto de Git Flow, os pull requests geralmente seguem esta lógica:

    • Feature → Develop: revisão de novas funcionalidades;

    • Develop → Main: preparação para produção;

    • Hotfix → Main: correções urgentes.

    Esse controle garante que cada ambiente (desenvolvimento, testes e produção) receba apenas código validado. Retomando o exemplo do e-book apresentado anteriormente, o pull request funciona como o momento em que o escritor entrega o capítulo para o revisor. O revisor analisa o conteúdo, sugere ajustes e aprova a publicação. Somente após essa validação o capítulo é integrado ao livro final. Não obstante, plataformas modernas permitem integrar pull requests com pipelines de CI/CD.

  • Releases para versionamento oficial do projeto: Releases fecham o ciclo de versionamento e dão “valor oficial” ao que foi desenvolvido. As Releases representam versões oficiais e estáveis de um projeto, marcando pontos específicos do seu ciclo de evolução. Diferentemente de commits individuais, que registram alterações pontuais, uma release consolida um conjunto de mudanças que foram testadas, revisadas e aprovadas, estando prontas para uso em produção ou distribuição.

  • Integração com pipelines de CI/CD: A integração com pipelines de CI/CD (Continuous Integration / Continuous Delivery ou Continuous Deployment) representa a evolução natural do uso de repositórios e versionamento de código. Enquanto o Git organiza e controla as alterações, os pipelines de CI/CD automatizam o processo de validação, testes, empacotamento e entrega do software, garantindo que cada mudança siga um fluxo padronizado e confiável até a produção.

    No contexto da Engenharia de Dados, pipelines de CI/CD são fundamentais para garantir a consistência e a estabilidade de processos como ingestão de dados, transformações, cargas em bancos de dados e execução de jobs analíticos.

Conceitos Fundamentais no Git

    Alguns conceitos são fundamentais para o entendimento do funcionamento do Git e das plataformas associadas:

  • Commit: Uma confirmação de um registro alterado no código, representando uma nova versão.

  • Branch: ramificação do código que permite o desenvolvimento paralelo. Exemplos como develop e features.

  • Pull Request: solicitação para que alterações de uma branch sejam revisadas e integradas a outra.

  • Release: versão estável do projeto, geralmente associada a uma entrega oficial.

  • Main (ou Master): branch principal, normalmente associada ao ambiente de produção.

Git Flow e Boas Práticas de Branches

    Uma das estratégias mais conhecidas de organização de repositórios é o Git Flow, que define papéis claros para cada branch:

  • Main (ou Master): representa o código em produção.

  • Develop: ambiente de desenvolvimento e integração.

  • Feature: utilizada para o desenvolvimento de novas funcionalidades.

  • Release: preparação de uma nova versão para produção.

  • Hotfix: correções urgentes aplicadas diretamente sobre a produção.




    Esse modelo permite que múltiplos desenvolvedores trabalhem simultaneamente sem interferir no trabalho uns dos outros, garantindo maior estabilidade ao projeto. 

Iniciando um Projeto com Git:

Criação e Inicialização de Repositórios

    O início de um projeto versionado com Git pode ocorrer de duas formas principais: por meio da criação de um repositório do zero ou pela clonagem de um repositório já existente:

  • git init: utilizado para criar um novo repositório Git local, iniciando o versionamento de um projeto do zero.

  • git clone: utilizado para copiar um repositório remoto existente para o ambiente local.

  • git push: envia alterações confirmadas (commits) do repositório local para o repositório remoto.

  • Pull Request: mecanismo utilizado para solicitar a integração de uma branch (geralmente uma feature) em outra branch, como a de desenvolvimento (develop).

Antes de iniciar qualquer projeto, é necessário que o Git esteja instalado na máquina do desenvolvedor. A ferramenta pode ser obtida no site oficial:

https://git-scm.com/downloads

    No ambiente Windows, o Git fornece um terminal próprio chamado Git Bash, que permite a execução de comandos Git e comandos de sistema de forma integrada. Além do ambiente Windows, o Git é amplamente utilizado em sistemas operacionais baseados em Unix, como Linux e macOS, que oferecem suporte nativo a terminais e ferramentas de linha de comando. O Linux é um dos ambientes mais tradicionais para o uso do Git, especialmente em contextos de servidores, desenvolvimento backend e Engenharia de Dados. Nesse sistema operacional, o Git é executado diretamente no terminal, sem a necessidade de ferramentas adicionais.

Criando o Primeiro Repositório Local

    Após a instalação do Git, o primeiro passo é criar um diretório que representará o projeto. No terminal Git Bash, utiliza-se o comando:

mkdir project

    O comando mkdir (make directory) cria uma nova pasta chamada project. Para acessar esse diretório, utiliza-se:

cd project

    Dentro da pasta do projeto, é possível inicializar o repositório Git local com o comando:

git init

    Esse comando cria a estrutura interna do Git no sistema operacional, incluindo a pasta oculta .git, responsável por armazenar todo o histórico de versionamento. Por ser uma pasta oculta, ela não aparece em listagens comuns de arquivos. Nesse momento, o projeto passa a ser versionado localmente, e a branch principal é criada automaticamente (normalmente chamada de main).




Criação da Branch de Desenvolvimento

    Como boa prática de versionamento, recomenda-se que o desenvolvimento não seja realizado diretamente na branch principal. Para isso, cria-se uma branch de desenvolvimento a partir da branch main:

git checkout -b develop

    

Esse comando cria a branch develop e já altera o contexto de trabalho para ela. A partir dessa branch, outras branches podem ser criadas, como branches de funcionalidades (feature branches), dependendo da complexidade do projeto.

                                                                        

Criação e Modificação de Arquivos

Com a branch de desenvolvimento ativa, podem ser criados arquivos no projeto. Aqui seguem arquivos simples somente para ilustração, tudo irá depender do contexto e requisitos de negócios. Por exemplo:

touch file1.txt touch file2.txt

Esses arquivos passam a existir no diretório do projeto e podem ser visualizados com o comando:

ls

Entretanto, apesar de existirem no diretório, esses arquivos ainda não estão sendo rastreados pelo Git. Para verificar o estado do repositório, utiliza-se:

git status

O comando git status exibe os arquivos não rastreados (untracked files) e informa que eles ainda não fazem parte do controle de versão.



Edição de Arquivos e Área de Stage

Antes de confirmar os arquivos no repositório, é possível editá-los. Um editor de texto comum em ambientes de terminal é o vi:

vi file1.txt

No editor vi, utiliza-se:

  • Esc + a para entrar no modo de inserção de texto;

  • Esc + :wq para salvar as alterações e sair do editor.

Após a edição, o conteúdo do arquivo pode ser exibido no terminal com:

cat file1.txt

Para que o Git passe a rastrear o arquivo editado, utiliza-se o comando:

git add file1.txt



    Esse comando move o arquivo para a área de stage, uma zona intermediária onde o Git aguarda a confirmação das alterações. O arquivo ainda não foi definitivamente inserido no repositório.

Confirmando Alterações com Commit

Para registrar oficialmente as alterações no histórico do projeto, utiliza-se o comando commit:

git commit -m "arquivo novo file1"

    O commit cria uma nova versão do projeto, associando uma mensagem descritiva às alterações realizadas. Após isso, ao executar novamente git status, o arquivo file1.txt não aparecerá mais como pendente.

    O arquivo file2.txt, por sua vez, ainda permanece como não rastreado, pois não foi adicionado à área de stage.

Rastreamento Múltiplo e Atualizações

    O arquivo file2.txt também pode ser editado utilizando o editor vi. Após inserir conteúdo e sair do editor, o comando git status continuará indicando que ele não está sendo rastreado. Além disso, caso um arquivo já rastreado, como o file1.txt, seja novamente modificado, o Git indicará que ele sofreu alterações. Nesse contexto, surgem conceitos importantes como diferenças entre versões e conflitos, que podem ocorrer quando múltiplas alterações competem entre si.

Para adicionar todos os arquivos modificados e não rastreados de uma só vez à área de stage, utiliza-se:

git add .

    Esse comando adiciona todos os arquivos do diretório atual à área de stage. Para confirmar que eles estão prontos para o commit, executa-se novamente o 

git status

Histórico de Versões

Após a confirmação final:

git commit -m "Inserindo os arquivos que estavam no diretório"

Os arquivos passam a fazer parte do repositório local de forma definitiva. O histórico completo de commits pode ser visualizado com:

git log

Esse comando exibe informações como autor, data, mensagem do commit e o identificador único (hash), que permite rastrear cada alteração realizada no projeto.


Considerações Finais

    Os comandos apresentados representam o fluxo essencial para a criação de um repositório Git do zero, bem como para a inserção, modificação e versionamento inicial de arquivos. O domínio desses conceitos é fundamental para a organização, rastreabilidade e colaboração em projetos de Engenharia de Dados e desenvolvimento de software.

Python e SQL na Engenharia de Dados

Python: Linguagem Versátil e Poderosa para Engenharia de Dados

    O Python é amplamente reconhecido como uma das linguagens mais versáteis e poderosas para a Engenharia de Dados. Diferentemente de outras linguagens de programação, que exigem maior esforço na definição de padrões, organização estrutural rígida e declaração explícita de tipos, o Python se destaca por sua simplicidade, legibilidade e produtividade, permitindo que resultados sejam alcançados com menor complexidade de implementação. Essa característica torna o Python especialmente adequado para ambientes de dados, nos quais a agilidade no desenvolvimento e a clareza do código são fatores críticos.

Na Engenharia de Dados, o Python é utilizado em diversas etapas do ciclo de vida dos dados, como:

  • Integrações entre sistemas;

  • Processamentos de dados em larga escala;

  • Desenvolvimento de pipelines de dados;

  • Construção de dashboards e relatórios analíticos.

   Ferramentas amplamente utilizadas no mercado, como Databricks, Apache Spark e Apache Airflow, utilizam Python como linguagem principal ou de suporte para orquestração, transformação e processamento distribuído de dados. Além disso, frameworks como Jupyter Notebooks oferecem um ambiente interativo que facilita análises exploratórias, testes de pipelines e validação de resultados.

     O grande objetivo do Python na Engenharia de Dados é permitir a representação e manipulação de dados de forma estruturada e intuitiva. A linguagem possibilita trabalhar com dados tabulares utilizando listas e dicionários, além de permitir a transformação de dados no formato chave–valor (NoSQL) em estruturas tabulares, facilitando análises, integrações e persistência em bancos de dados relacionais.

SQL na Engenharia de Dados e sua Integração com Python

    A SQL (Structured Query Language) é uma linguagem essencial na Engenharia de Dados, sendo utilizada para acessar, consultar, manipular e administrar dados armazenados em sistemas gerenciadores de bancos de dados (SGBDs). Uma de suas principais vantagens é a universalidade, pois pode ser utilizada em praticamente todos os SGBDs disponíveis no mercado, como:

  • MySQL

  • PostgreSQL

  • Oracle

  • SQL Server

  • SQLite

    Essa padronização facilita a transição entre diferentes sistemas de banco de dados e torna a SQL uma linguagem indispensável tanto para ambientes transacionais quanto analíticos, especialmente em cenários com grandes volumes de dados.

    Embora alguns SGBDs possuam extensões específicas, como o PL/SQL no Oracle, os fundamentos da linguagem SQL permanecem consistentes, permitindo reaproveitamento de conhecimento e maior interoperabilidade.

Na Engenharia de Dados, a SQL é amplamente utilizada para:

  • Recuperação e extração de dados;

  • Criação de relatórios;

  • Apoio à análise de dados;

  • Preparação de dados para consumo por aplicações e pipelines.

    Em conjunto com o Python, a SQL torna-se ainda mais poderosa, pois os dados recuperados podem ser transformados, enriquecidos e analisados programaticamente, ampliando as possibilidades de uso.

Integração do SQLite com Python

    Para exemplificar a integração entre Python e SQL, pode-se utilizar o SQLite, um banco de dados leve, amplamente adotado em ambientes educacionais, prototipação e aplicações locais. O SQLite permite a manipulação de dados diretamente a partir do Python, sem a necessidade de um servidor de banco de dados dedicado.

    Antes de iniciar, é recomendável configurar um ambiente isolado de desenvolvimento. Após a ativação do ambiente virtual, o projeto estará preparado para trabalhar com Python, SQLite e ferramentas como Jupyter Notebook, garantindo isolamento de dependências e maior organização do desenvolvimento.


    Aqui temos um exemplo prático de inicialização de um banco de dados teste. Todo o processo de abertura do diretório projeto foi realizado, além de, também, ativar o ambiente virtual e instalar todas as dependências necessárias pra começar o projeto.

    Ao importar o módulo sqlite3, o Python passa a ter acesso nativo às funcionalidades do SQLite, dispensando a instalação de bibliotecas externas. O comando sqlite3.connect('teste.db') estabelece a conexão com o banco de dados. Caso o arquivo teste.db não exista no diretório do projeto, o SQLite realiza automaticamente sua criação.

    O objeto cursor atua como um driver de execução, sendo responsável por enviar instruções SQL ao banco de dados. Por meio do método execute, é possível criar tabelas, definir atributos, inserir dados e realizar consultas.

    No exemplo apresentado, o comando CREATE TABLE IF NOT EXISTS garante que a tabela pessoas seja criada apenas se ainda não existir, evitando erros de execução em múltiplas inicializações do projeto. Essa prática é especialmente importante em pipelines de dados e aplicações que podem ser executadas mais de uma vez.

A tabela definida contém:

  • Um campo id como chave primária, com incremento automático;

  • Campos textuais e numéricos com restrições NOT NULL, assegurando a integridade dos dados.

Esse exemplo consolida o processo de preparação do ambiente de desenvolvimento, que inclui:

  • Criação do diretório do projeto;

  • Inicialização do repositório Git;

  • Integração entre Python e SQL.

    A partir dessa base, o projeto está preparado para evoluir, permitindo a inserção de dados, execução de consultas SQL, transformação das informações com Python e, posteriormente, a integração com ferramentas mais avançadas da Engenharia de Dados, como pipelines automatizados e versionamento remoto.

Compreensão Interna da Execução de Código em Programação

print(cursor)  # Representação do cursor = Endereço na memória
print(repr(cursor))
hex(id(cursor))  # Endereço na memória
print(type(cursor))  # Imprime o tipo do objeto
print(cursor.connection)   # O connection já é outro lugar na memória
print(cursor.execute)   # Imprime o método como objeto
print(type(cursor.execute))  # Imprime o tipo do objeto ou método
# Como o sqlite3.Cursor é uma classe nativa (não dá pra alterar direto), fazemos um wrapper.
# Conceito importante (vale guardar) : '__repr__' serve para representar estado, não dados.
# Para representar os dados, devemos iniciar com uma consulta, exemplo: SELECT

Saídas esperadas:

<sqlite3.Cursor object at 0x0000023978897D40> <sqlite3.Cursor object at 0x0000023978897D40> <class 'sqlite3.Cursor'> <sqlite3.Connection object at 0x0000023978E245E0> <built-in method execute of sqlite3.Cursor object at 0x0000023978897D40> <class 'builtin_function_or_method'>   

    É importante saber os bastidores de cada linha que executamnos porque nenhuma linha de código é isolada: toda instrução cria efeitos na memória, altera estados internos, consome recursos da sua máquina e interage com abstrações que não vemos diretamente.

    Quando entendemos esses bastidores, deixamos de enxergar o código apenas como “comandos que funcionam” e passamos a enxergá-lo como operações sobre objetos, dados e estados. Isso nos permite prever comportamentos, evitar efeitos colaterais inesperados e tomar decisões mais conscientes sobre desempenho, segurança e manutenção.

    Conhecer o que acontece por trás de cada linha também nos dá capacidade real de depuração. Em vez de apenas reagir a erros, conseguimos identificar 'por que' eles ocorrem. Se o problema está na criação de um objeto, devemos saber então se ele é nativo ou não, um ciclo de vida de uma conexão, no reaproveitamento indevido de recursos ou na forma como a linguagem gerencia memória e exceções.

Vamos a algumas resoluções:

print(cursor)

Imprime a representação padrão do objeto sqlite3.Cursor.

Isso não mostra dados mas mostra o tipo do objeto que o SQLite usa e o endereço de memória dentro da sua máquina! Os dados mesmo, ainda não foram inseridos.   Qual a importância disso?  Em classes nativas como sqlite3.Cursor, não temos controle sobre isso! 

hex(id(cursor))

Mostra o endereço de memória do objeto.

  • id(cursor) → retorna um inteiro único ( padrão SQL )

  • hex() converte para hexadecimal

Tá, e qual a importância disso? Que dois objetos diferentes sempre terão IDs diferentes

  • E o 'cursor' é um objeto vivo na memória, não uma cópia!

print(type(cursor))

Mostra o tipo exato do objeto. Sua saída típica é : <class 'sqlite3.Cursor'>

  • Confirma que 'cursor' é uma instância da classe 'Cursor', não é lista, tupla, iterator, etc.

print(cursor.connection)

Mostra o objeto de conexão associado ao cursor.

  • <sqlite3.Connection object at 0x0000021A3F8C9D50>
  • Demonstra que o 'cursor' não é independente e ele aponta para uma Connection, que é outro objeto na memória. Relação:

Connection → cria → Cursor → executa SQL

print(cursor.execute)

Imprime o método execute como objeto alocado em memória.

  • Saída típica:

    <built-in method execute of sqlite3.Cursor object at 0x...>
  • Isso prova que métodos também são objetos e 'execute' é um método embutido (built-in). Métodos 'built-in' são classes nativas em Python! Não temos controle sobre isso!

print(type(cursor.execute))

Mostra o tipo do método. Por isso sabemos que é uma classe. Geralmente mostra isso:

  • <class 'builtin_function_or_method'>
  • Indica que não é uma função Python comum e é implementado em C, dentro do SQLite.

Conceito-chave:

'__repr__ ' é um método especial em Python que representa estado do objeto, não os dados. O cursor não guarda dados ele apenas aponta para uma consulta e controla execução!


Considerações:

    Saber os “bastidores” (como objetos, memória, tipos e métodos realmente funcionam) não é curiosidade acadêmica , é maturidade técnica. Vou te explicar por que isso importa na prática, especialmente no tipo de código que você costuma escrever (Python, banco de dados, testes, SQLAlchemy/SQLite).


Importâncias:

Pare de programar por 'tentativa e erro':

    Quem não entende bastidores fica só copiando códigos, ajusta até “funcionar” e não sabe o porquê de não funcionar. Quem entende as representações prevê comportamentos,  sabe o que pode quebrar e corrige o problema na raiz.

Exemplo real é declarar :

cursor2 = cursor

Sem bastidores podemos 'achar' que criou outro cursor mas apontam para o mesmo objeto na memória criando mais linhas de códigos desnecessários e evita bugs indesejáveis!

    Você entende bugs que outros não conseguem explicar. Muitos erros não estão no SQL e nem no Python! Eles estão como um objeto fechado que você nunca saberá porque ele não muda o estado dele até entender que é built-in.

Você entende estado vs dados :

    Volto a tocar em um ponto muito importante '__repr__' representa estado, não dados! O 'cursor' por sua vez representa o estado da conexão, ( confirmada, fechada, realizada ) e sua posição dentro da sua máquina e os dados só existem depois de SELECTQuem não entende isso tenta imprimir cursor esperando dados,  faz debug errado e cria logs inúteis.

Você passa a escrever código testável e explicável:

    Quando você sabe o tipo real do objeto (  seu comportamento típico para o qual foi criado ), origem do método e ciclo de vida na memória, você consegue 'mockar corretamente' ( Técnicas de testes para análise de comportamentos em representações das classes e métodos ), melhorar logs ( informações sobre os testes dos scripts ) e escrever __repr__ úteis.  Isso é engenharia, não script.

Você deixa de 'brigar' com bibliotecas:

    Muita frustração vem disso de: 'Ah, o framework não faz o que eu quero'. Na verdade ele faz exatamente o que foi projetado para fazer você só não conhece os limites e saber que sqlite3.Cursor é nativo e usa métodos são em C e __repr__ não é customizável.

Você ganha autonomia técnica (isso pode mudar sua carreira)

    Quem entende os bastidores não depende tanto de respostas prontas, lê a documentação mais rápido, entende código alheio e explica decisões técnicas!

Guarde essa:

Quem entende os bastidores controla o código!
Quem não entende, é controlado por ele!


Considerações Finais

    Python e SQL formam a base técnica da Engenharia de Dados moderna. Enquanto a SQL permite o acesso eficiente a dados estruturados, o Python amplia as possibilidades de transformação, integração e análise. A combinação dessas tecnologias, aliada a boas práticas de versionamento e automação, possibilita a construção de soluções escaláveis, confiáveis e alinhadas às demandas do mercado. 

    No início deste trabalho, optou-se por usar exclusivamente com um repositório Git local, sem integração imediata com um repositório remoto. Essa abordagem é comum e recomendada nas fases iniciais de desenvolvimento, especialmente quando o objetivo é estruturar o projeto, validar conceitos e organizar o código antes de torná-lo público ou compartilhado.

    O uso do Git em ambiente local permite que o desenvolvedor compreenda de forma aprofundada os fundamentos do versionamento, como criação de branches, histórico de alterações e sem a complexidade adicional da colaboração remota. Nesse estágio, o foco está na organização do código, experimentação e consolidação da base do projetoAlém disso, o versionamento local possibilita maior liberdade para refatorações, testes e ajustes estruturais, uma vez que as alterações ainda não impactam outros desenvolvedores ou ambientes externos. Essa prática contribui para a qualidade inicial do projeto e reduz retrabalho em fases posteriores.

    Somente após a estabilização da estrutura do projeto, definição de padrões e validação dos fluxos de desenvolvimento é que a integração com um repositório remoto se torna recomendada. Nesse momento, o repositório passa a assumir um papel colaborativo, permitindo revisões de código, controle de permissões, automação de pipelines e versionamento oficial por meio de releases.

    Dessa forma, o início do trabalho com um repositório exclusivamente local não representa uma limitação, mas sim uma estratégia consciente, alinhada às boas práticas de desenvolvimento. Essa abordagem garante uma base sólida para a evolução do projeto, facilitando sua posterior integração com plataformas de gerenciamento de repositórios e fluxos de CI/CD.

    Com a estrutura inicial do trabalho estabelecida e a integração entre Python e SQL validada em ambiente local, os próximos passos envolvem o aprofundamento no tratamento e na análise de dados. Serão abordados conceitos mais avançados de SQL, como joins entre tabelas, além da manipulação de dados por meio de DataFrames utilizando a biblioteca Pandas, amplamente adotada na Engenharia de Dados.

    Adicionalmente, o projeto evoluirá para a integração com um repositório remoto, permitindo a centralização do código, a colaboração, o uso de pull requests e a adoção de boas práticas de versionamento, consolidando o ciclo completo de desenvolvimento e entrega.




Comentários

Postagens mais visitadas deste blog

Projeto de Banco de Dados: Setor Varejo

Projeto Prático de Engenharia de Dados com Python, SQL e GitHub