Um dos principais problemas para a criação de sistemas de ciência de dados é a criação de bases de teste, estas correspondem à muitas entradas e as formas tradicionais que envolvem a utilização de fixtures or roll-backs passam a ser muito trabalhosas, A Murabei DS desenvolveu uma imagem docker com um banco de dados Postgres12 com extensão Timescale que tem seus dados regenerados após uma chamada get no end-point /reload-db/
.
A base de dados regen-timescale-db regenera para os dados originais quando chamada em /reload-db/
Essa imagem é fruto de desenvolvimento interno da Murabei DS e é utilizada hoje no desenvolvimento de testes para o PUMPWOOD. Seu código é baseado na imagem postgres e timescale-db e está disponível no DockerHub e no Github.
A possibilidade de regenerar a base de dados utilizando uma chamada API facilita a utilização da imagem para o desenvolvimento de micro serviços e permite que possam ser criadas imagens com dados diferentes para testes específicos. Segue abaixo alguns exemplos de utilização:
1º passo: dump da base de dados
A 1a coisa a ser feita é o dump da base de dados que será utilizada para os testes.
PGPASSWORD=is_very_nice! pg_dump --disable-triggers -h localhost -p 5432 -U murabei --superuser murabei > database.sql
2º passo: build da imagem regen
A 2a coisa é fazer o build da imagem usando o dump da base de dados, segue um exemplo do DockerFile:
FROM andrebaceti/regen-timescale-db:0.0 ############################################ # Use the same values of the dumped database ENV POSTGRES_USER="murabei" ENV POSTGRES_DB="murabei" ENV POSTGRES_PASSWORD="is_very_nice!" ############################################### # Name of the app, this will be used to set the # regen end-point ENV APP_NAME="regen-test" ################################################################# # Copy the dumpfile to docker-entrypoint-initdb.d so # the dumped database will be recriated when the container starts COPY database/database.sql /docker-entrypoint-initdb.d/database.sql RUN chmod 777 -R /docker-entrypoint-initdb.d/
3º passo: criar nosetests (ou coisa do tipo) usando a imagem
Para regenerar a base de dados é necessário chamar o end-point reload-db entre os testes ou mesmo durante os testes se for necessário. Segue abaixo um exemplo de unittest em Python, mas algo semelhante poderia ser programado em qualquer linguagem, basta chamar o end-point de regeneração.
"""Sets an example for nosetests using regen postgres image.""" import unittest import requests import pandas as pd from sqlalchemy import create_engine class TestExample(unittest.TestCase): """Unittest class that helps building pumpwood based systems test.""" con_str = "postgresql://murabei:is_very_nice!@localhost/murabei" def setUp(self, *args, **kwargs): """Regen the database in the setUp calling reload end-point.""" ###################### # Regenerate database# for app in self.apps_to_regenerate: response = requests.get( "http://0.0.0.0:5000/reload-db/regen-test/") if response.status_code != 200: raise Exception(app + ' regenerate: ', response.text) def test__1(self): """Check if database has regen after call.""" engine = create_engine(self.con_str) counts_start = pd.read_sql(""" SELECT var, COUNT(*) AS count_start FROM data GROUP BY var """, con=engine) # Removing some rows... engine.execute("DELETE FROM data WHERE var='murabei'") counts_delete = pd.read_sql(""" SELECT var, COUNT(*) FROM data GROUP BY var """, con=engine) self.assertNotIn('murabei', counts_delete["var"]) # Regenerate database response = requests.get( "http://0.0.0.0:5000/reload-db/regen-test/") response.raise_for_status() # Check if database has regenerate counts_final = pd.read_sql(""" SELECT var, COUNT(*) AS count_final FROM data GROUP BY var """, con=engine) pd_check_data = counts_final.merge(counts_start) check = ( pd_check_data["count_final"] == pd_check_data[ "count_start"]).all() self.assertTrue(check)
Feliz Natal comunidade!
Essa imagem é muito últil para o desenvolvimento de sistemas em microserviços onde mais de um pode modificar a base de dados e facilita no teste de migrações, permitindo o rollback. Outra facilidade é ser possível versionar facilmente as bases de testes usando as imagens docker. O código está licenciado em MIT License.
Feliz natal comunidade! A Murabei DS acredita no desenvolvimento colaborativo com a partcipação da comunidade, parceiros e universidade. Afinal, o que seria da ciência de dados sem tantas tecnologias open-source… Python, R, Flask, Django, ScikitLearn, pandas, timescaleDB, Postgres, NGINX… tem tantas que não cabe aqui no post.
Links
https://hub.docker.com/repository/docker/andrebaceti/regen-timescale-db
https://github.com/andrebaceti/regen-timescale-db