CouchDB, um banco de dados NoSQL, serverless e com sincronização offline

O CouchDB é um banco de dados especial, com funcionalidades que nenhum outro banco de dados oferece nativamente. O seu diferencial é permitir sincronização master master de forma fácil (sincronização offline e entre diferentes clusters de banco de dados), trabalhar com dados no formato JSON, e poder ser serverless (ou seja, permitir criar uma aplicação sem back-end, apenas CouchDB e front-end!).

Um tutorial introdutório muito bom é o A Pokemon Crash Course on CouchDB, nele aprendemos como fazer coisas básicas e importantes no CouchDB.

Também há um tutorial escrito por um dos criadores do CouchDB. Esse tutorial é mais completo contém trechos do livro mais completo de CouchDB, mas não contém tudo que tem no livro (isca pra comprar o livro). O livro é certamente a introdução mais completa que você pode ter.

Outra alternativa é usar a documentação do CouchDB. A documentação com certeza é o lugar mais completo pra se ter informações, só que não necessariamente as coisas estarão do jeito mais didático.

Visualizando Dados Salvos

Por GET

O GET permite visualizar um documento apenas.

  • Se você tem o id do documento, pode informá-lo ao CouchDB e obter os dados e o id da última versão salva.
  • Se você tem o id do documento e o id da versão, pode obter os dados referentes a ele.

Por Views

É uma das formas mais robustas de acessar os dados. As Views também criam índices, o que deixa seu acesso muito rápido.

Pelo Mango

O Mango é uma linguagem de query semelhante à usada no MongoDB. Ela dá facilidade para acessar os dados. Tomar cuidado com o Mango pois não é uma função madura o suficiente.

Usando o CouchDB de forma Serverless e Segurança

O CouchDB permite criarmos aplicações sem precisarmos de um backend, isso é muito bom e traz uma rapidez enorme no desenvolvimento. Mas… O CouchDB tem algumas limitações ao atuar como backend e banco de dados ao mesmo tempo, e essas limitações estão relacionadas a segurança.

Que limitações de segurança são essas?

O CouchDB tem 2 tipos de usuários

  • Administrador do Servidor (acesso a todos os bancos de dados do servidor)
  • Administrador do Banco de Dados (acesso a um banco de dados específico)

Tendo isso em mente, você precisará arquitetar seu banco com base nisso. Por padrão não é possível dar permissões para um pedaço do banco de dados, é tudo ou nada.

Como dar permissões de leitura apenas?

Basta utilizar o conceito de validation function. Para quem está acostumado com triggers no SQL, é basicamente uma trigger. Um usuário tem apenas permissão de leitura para o banco. Quando ele tentar criar, editar ou apagar um documento, esta validation function é chamada e a sua ação é ignorada. Eis um exemplo:

https://jamesadam.me/2014/11/09/couchdb-authorization/

https://stackoverflow.com/questions/10713437/couchdb-wide-read-only-access-rights

http://guide.couchdb.org/draft/security.html

Uma alternativa… ACL no CouchDB!

Esforços estão sendo desenvolvidos para criar um ACL a nível de banco de dados, e isso se chama Cover Couch, mas os desenvolvimentos estão em fase beta.

https://github.com/ermouth/covercouch

Referências em Serverless CouchDB

https://www.joshmorony.com/creating-a-multiple-user-app-with-pouchdb-couchdb/

Como o CouchDB funciona?

Esse artigo de blog explica muito bem várias características do CouchDB, inclusive sobre performance e fazendo analogias do CouchDB com o SQL.

A analogia mais interessante foi:
databases (bancos de dados) no CouchDB são como tabelas no SQL
views (visualizações) no CouchDB são como índices num banco de dados SQL.

O que todo desenvolvedor precisa saber sobre CouchDB
https://www.dimagi.com/blog/what-every-developer-should-know-about-couchdb/

Views no CouchDB

Um exemplo completo de Views no CouchDB

https://www.lullabot.com/articles/a-recipe-for-creating-couchdb-views

Filtrando uma View por data no CouchDB

https://dzone.com/articles/multiple-search-keys-in-couchdb

https://medium.com/ibm-watson-data-lab/creating-partial-cloudant-indexes-1ebf169c8e15

https://forums.couchbase.com/t/filtering-data-based-on-datetime/366

Lidando com memória em uma aplicação Python que rodará por um longo tempo

O Python tem um garbage collector, mas não é tão bom quanto o Java, então em algumas aplicações para rodar initerruptamente é importante monitorar o estado da memória do programa e apagar da memória variáveis e objetos não utilizados.

Visualizando a memória utilizada pelo seu programa no Python

Usando o resource

Se o Python rodar em Linux, basta usar a biblioteca resource:

import resource
<span class="pln">resource</span><span class="pun">.</span><span class="pln">getrusage</span><span class="pun">(</span><span class="pln">resource</span><span class="pun">.</span><span class="pln">RUSAGE_SELF</span><span class="pun">).</span><span class="pln">ru_maxrss</span>

Usando o memory_profiler

Mostra o uso da memória em tempo real no console
https://www.dev2qa.com/python-profile-memory-usage-and-object-graph-example/

Usando o objgraph

Cria um grafo das relações entre os objetos no programa.
https://www.dev2qa.com/python-profile-memory-usage-and-object-graph-example/

Outras dicas para otimizar memória

https://dzone.com/articles/python-memory-issues-tips-and-tricks

Forçando Python a limpar a memória

Chamando o garbage collector

gc.collect

Marcando variáveis e objetos para serem deletados pelo garbage collector

chamar o del:

Dando override no método __del__

implementando seu próprio __del__

Resposta interessante sobre como limpar a memória

https://stackoverflow.com/a/38545526/2789895

Criando um websites serviços web que funcionem offline

Acredito que sempre teremos problemas de conexão com a internet, mesmo tendo cada vez mais acesso à internet rápida, estáveis e de baixo custo.

Algumas tecnologias web, hoje, permitem criarmos websites que funcionem offline. Um bom exemplo é o do Google Drive, que funciona até mesmo quando não estamos conectados.

Uma das tecnologias que permitem isso é o Service Worker. Não sei exatamente como funciona, mas esse carinha do Google Developers sabe, e sabe muito bem.

Outra tecnologia interessante é o PouchDB, uma “cópia” do Apache CouchDB feita totalmente em JavaScript. E o que é o CouchDB? É um banco de dados NoSQL! O foco do CouchDB é aplicações serverless (ou seja, sem backend!) e permitir sincronizações (de todo o tipo, master-master, master-slave…) entre seus bancos.

O PouchDB tem o poder manter um banco de dados NoSQL offline, e assim que a conexão voltar, sincronizar dados novos com um servidor CouchDB. Bem interessante!

Trabalhando com Pandas e Python

CheatSheet de Pandas

Uma lista com vários códigos úteis
https://morphocode.com/pandas-cheat-sheet/

Pandas para pessoas do SQL

Um tutorial com consultas em SQL e seus equivalentes no Pandas
https://hackernoon.com/pandas-cheatsheet-for-sql-people-part-1-2976894acd0

Criando uma coluna a partir do valor de outras em um DataFrame

df[‘nova_coluna’] = df.apply(lambda row: )

Tipos de dados no Pandas

Tome muito cuidado com as conversões automáticas utilizando category no pandas.

Mudando o tipo de uma coluna numpy datetime64 no pandas

df[‘day’] = df[‘day’].values.astype(‘datetime64[M]’)

https://stackoverflow.com/questions/40039457/how-to-change-date-in-pandas-dataframe

Deletando linhas no Pandas

https://chrisalbon.com/python/data_wrangling/pandas_dropping_column_and_rows/

Aumentando o limite de linhas mostradas pelo visualizador

pd.options.display.max_rows = 999

Referência

https://stackoverflow.com/questions/26886653/pandas-create-new-column-based-on-values-from-other-columns

Filtrando e cortando um dataframe com multi índices

Faz o uso das operações iloc, loc e ix.

https://www.somebits.com/~nelson/pandas-multiindex-slice-demo.html

Using iloc, loc, & ix to select rows and columns in Pandas DataFrames

Fazendo shift em um dataframe com multi índices

https://stackoverflow.com/questions/23198053/how-do-you-shift-pandas-dataframe-with-a-multiindex

Dicas de manipulação de TimeSeries no Pandas

https://s3.amazonaws.com/assets.datacamp.com/production/course_5702/slides/chapter1.pdf

Como fazer operações com dados geoespaciais no Pandas?

Há uma biblioteca chamada geopandas que tenta adicionar essa funcionalidade ao pandas. A página do Git contém uma documentação breve. A documentação mostra outras questões mais detalhadas.

Apresento um tutorial bem bacana ali nas referências.

Manual do Shapely

https://shapely.readthedocs.io/en/stable/manual.html

Como descobrir os ângulos entre dois pontos?

https://glenbambrick.com/tag/shapely/

https://www.packtpub.com/mapt/book/application_development/9781783552429/5/ch05lvl1sec56/calculating-line-direction

https://docs.scipy.org/doc/numpy/reference/generated/numpy.arctan2.html

https://stackoverflow.com/questions/9970281/java-calculating-the-angle-between-two-points-in-degrees

Referências para o GeoPandas

Spatial data, GeoPandas, and Pokémon: Part I
https://towardsdatascience.com/spatial-data-geopandas-and-pok%C3%A9mon-part-i-8525c801ed18

Geospatial Analysis with Python, GeoJSON and GeoPandas
https://www.twilio.com/blog/2017/08/geospatial-analysis-python-geojson-geopandas.html

Making Maps With Python mplleaflet
http://michelleful.github.io/code-blog/2015/07/15/making-maps/

Uma lista com todos os mapas que você pode usar na plotagem:
https://github.com/jwass/mplleaflet/blob/master/mplleaflet/maptiles.py

Geopandas: Transformando pontos de GPS em linhas

Qual a diferença entre dados do tipo Vector e Raster?

Vector vs Raster: What’s the Difference Between GIS Spatial Data Types?

Deixando o uso de memória no Pandas mais leve

https://www.dataquest.io/blog/pandas-big-data/

Criando um projeto no GIT pelo PyCharm/IntelliJ/JetBrains

  1. VCS
  2. Enable Version Control Integration
  3. Git

Pronto, agora um repositório GIT local foi criado!

A primeira coisa mais importante agora é criar o arquivo .gitignore. Você pode gerar um aqui.

Agora, perceba que todos os seus arquivos estão em vermelho, ou seja, eles não fazem parte do repositório. Você precisa adicioná-los manualmente. Adicione os arquivos desejados.

Agora vamos adicionar um lugar na nuvem para publicar os arquivos:

  1. VCS
  2. Git
  3. Remotes…
  4. +
  5. Adicione a URL do seu repositório na nuvem (GitLab, GitHub, BitBucket…)

Se você está com problemas nessa parte você pode tentar o seguinte:

Baixar e reinstalar o GIT no seu computador

File -> Settings -> Version Control -> Git
Mudar o SSH Executable de Built-in para Native
Reiniciar o IntelliJ
(se não der certo, tentar voltar para Built-in)

Retornando linhas inseridas junto com um INSERT

Você pode retornar as linhas inseridas em um INSERT da seguinte forma:

INSERT INTO tabela (id, nome, valor)
VALUES (232,'Jonas',34343.34)
RETURNING id, nome, valor
--Ou para retornar todas as linhas: RETURNING *

Se você quiser fazer outro INSERT com o resultado da saída desse INSERT, pode fazer assim:

WITH ins AS (
INSERT INTO test (value)
VALUES (123.123123123)
RETURNING *
)
INSERT INTO test (value)
SELECT value
FROM ins;