okfn-brasil / gastos_abertos

Código principal do projeto Gastos Abertos.
GNU Affero General Public License v3.0
9 stars 7 forks source link

Criar script para inserir codigos da Receita #50

Closed aivuk closed 9 years ago

aivuk commented 9 years ago

A partir do arquivo:

https://github.com/okfn-brasil/gastos_abertos_dados/blob/master/doc/Codificacao_de_Receitas_2013.txt

para inserir os dados de acordo com o modelo criado em #49.

Veja a tarefa #51 para entender melhor como as strings serao salvas. Um exemplo, o codigo:

1121.03.00 Taxa de Controle e Fiscalização de Produtos Químicos

ficara salvo como "1.1.2.1.3". Note a exclusao dos zeros nao significativos.

andresmrm commented 9 years ago

O que quer dizer quando tem um: https://github.com/okfn-brasil/gastos_abertos_dados/blob/master/doc/Codificacao_de_Receitas_2013.txt#L506

aivuk commented 9 years ago

O nome da tabela pode ser RevenueCode e quanto as entradas bizarras N+, vamos ignorar no momento essas linhas (ou da uma lida no manual orcamentario que mandei pra lista antiga e veja se faz sentido disso)

andresmrm commented 9 years ago

Uma dúvida: precisamos mesmo pegar esses códigos de um PDF? As tabelas não servem? https://github.com/okfn-brasil/gastos_abertos_dados/tree/master/Orcamento/receitas/via_site_prefeitura

aivuk commented 9 years ago

Pegue o que for mais fácil, mas sinceramente, o .txt (não o pdf) que está no gastos_abertos_dados está bem mais fácil pra implementar um parser que essas tabelas. No arquivo txt pelo menos garante-se que aparece apenas uma vez a definição de cada código, neste arquivo aparecerá a descrição do código em cada nível mais de uma vez e deverá ser implementado um script que leve isso em consideração.

andresmrm commented 9 years ago

Na hora de importar os dados estou ganhando esse erro:

sqlalchemy.exc.ProgrammingError: (ProgrammingError) You must not use 8-bit bytestrings unless you use a text_factory that can interpret 8-bit bytestrings (like text_factory = str). It is highly recommended that you instead just switch your application to Unicode strings. u'INSERT INTO revenue (code, description) VALUES (?, ?)' ('1100.0.0', 'Receita Tribut\xc3\xa1ria')

Acha que é problema no model?

andresmrm commented 9 years ago

Coloquei um "unicode" como vc fez no seu importador. Agora estou recebendo esse:

2015-02-04 13:26:31,721 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 2015-02-04 13:26:31,721 INFO sqlalchemy.engine.base.Engine () 2015-02-04 13:26:31,722 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 2015-02-04 13:26:31,722 INFO sqlalchemy.engine.base.Engine () 2015-02-04 13:26:31,722 INFO sqlalchemy.engine.base.Engine BEGIN (implicit) 2015-02-04 13:26:31,723 INFO sqlalchemy.engine.base.Engine INSERT INTO revenue (code, description) VALUES (?, ?) 2015-02-04 13:26:31,723 INFO sqlalchemy.engine.base.Engine ('1000.0.0', u'Receitas Correntes') 2015-02-04 13:26:31,724 INFO sqlalchemy.engine.base.Engine COMMIT Traceback (most recent call last): File "import_revenue_codes.py", line 45, in codes_to_dict(arguments['TXT_FILE']) File "import_revenue_codes.py", line 37, in codes_to_dict "description": unicode(r.group("descr").strip()) UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 14: ordinal not in range(128)

Depois tento de novo. Ecoding sempre dá dor de cabeça...

aivuk commented 9 years ago

Resolvi, bastava abrir o arquivo com codecs.open. Além disso veja como realizei o insert agora. A vantagem de se utilizar o insert do SQLAlchemy está em poder criar um comando único de INSERT SQL para a inserção de múltiplos dados no DB. Você estava utilizando para fazer a inserção um código por vez, o que não faz muito sentido. Se fosse pra inserir um por vez, melhor seria ter feito apenas:

r = RevenueCode() r.code = "BLAH" r.description ="BLAH BLAH BLAH"

db.session.add(r) db.session.commit()

Outro detalhe é que estava inserindo na tabela errada (Revenue ao invés de RevenueCode).

andresmrm commented 9 years ago

Quoting aivuk (2015-02-04 15:17:01)

Resolvi, bastava abrir o arquivo com codecs.open. Além disso veja como realizei o insert agora. A vantagem de se utilizar o insert do SQLAlchemy está em poder criar um comando único de INSERT SQL para a inserção de múltiplos dados no DB. Você estava utilizando para fazer a inserção um código por vez, o que não faz muito sentido. Se fosse pra inserir um por vez, melhor seria ter feito apenas:

r = RevenueCode() r.code = "BLAH" r.description ="BLAH BLAH BLAH"

db.session.add(r) db.session.commit()

Ah, agora entendi porque você usou aquele comando. Não conhecia.

Outro detalhe é que estava inserindo na tabela errada (Revenue ao invés de RevenueCode).

Ops... Não tinha terminado de testar o código... =P

Vlw!

andresmrm commented 9 years ago

Estou tentando rodar o script, mas está dando:

sqlalchemy.exc.OperationalError: (OperationalError) no such table: revenuecode

Mesmo depois de ter dado:

fab reset
python manage.py initdb

Alguma ideia do porque?

aivuk commented 9 years ago

Você mudou o nome da tabela para revenue_code. O fab reset não está apagando o db antigo. Veja o arquivo:

/tmp/db.sqlite

Abra o db e confira o nome da tabela. Aqui rolou o código de criação com nome correto e importação.

aivuk commented 9 years ago

A tarefa não está implementada como especificada, estou reabrindo. Note o que foi dito sobre a exclusão de zeros não significativos, enquanto atualmente está sendo inserido coisas como '1774.0.0'. Deveria ser inserido apenas '1774' e '1920.0.0' deverá ser '1920'.

andresmrm commented 9 years ago

Tá... E se for '1000.00.13'? Como deve ficar? Outra dúvida, na última msg você disse que '1774.0.0' viraria '1774', mas segundo seus exemplos anteriores, não deveria virar '1.7.7.4'?

andresmrm commented 9 years ago

Descobri o problema com o nome da tabela. O GastosAbertos está instalado no meu VirtualEnv. Logo ele estava usando 'gastos-abertos/env/lib/python2.7/site-packages/gastosabertos-0.0.1-py2.7.egg/gastosabertos/receita/models.py', que estava desatualizado. Tem ideia do porque isso aconteceu?

andresmrm commented 9 years ago

Hum, acho que foi porque instalei o projeto com 'python setup.py install' e não 'python setup.py develop'. Agora parece que está certo.

andresmrm commented 9 years ago

Ainda sobre a conversão do código. Você converteu: '1121.03.00' para '1.1.2.1.3' no exemplo. E se fosse '1121.30.00'? Viraria '1.1.2.1.30'? Qual o critério para colocar '.' no meio de um número, como você está fazendo com os 4 primeiro dígitos?

aivuk commented 9 years ago

Descobri o problema com o nome da tabela. O GastosAbertos está instalado no meu VirtualEnv. Logo ele estava usando 'gastos-abertos/env/lib/python2.7/site-packages/gastosabertos-0.0.1-py2.7.egg /gastosabertos/receita/models.py', que estava desatualizado. Tem ideia do porque isso aconteceu?

Nos scripts em utils/ existe um import gastosabertos, se estiver dentro desse diretório ele irá busca no sistema por essa lib. Se der o comando "python manage.py run" na raiz do projeto, ele irá buscar localmente pela lib gastosabertos.

aivuk commented 9 years ago

Ainda sobre a conversão do código. Você converteu: '1121.03.00' para '1.1.2.1.3' no exemplo. E se fosse '1121.30.00'? Viraria '1.1.2.1.30'? Qual o critério para colocar '.' no meio de um número, como você está fazendo com os 4 primeiro dígitos?

O único critério é se garantirmos que os primeiro quatro níveis sempre possuem quatro dígitos. Se possuirem quatro dígitos é opcional intercalarmos os pontos. Mas talvez seja melhor intercalar os pontos para ficar mais fácil a implementação de códigos para converter uma lista de níveis para uma string pra ser utilizada na API.

andresmrm commented 9 years ago

Veja se agora está ok, por favor. Para exemplificar, o final do meu BD está ficando assim:

INSERT INTO "revenue_code" VALUES('2.1.0.0','Operações de Crédito'); INSERT INTO "revenue_code" VALUES('1.7.2.1.22.11','Cota-parte da Compensação Financeira de Recursos Hídricos'); INSERT INTO "revenue_code" VALUES('2.4.7.2.99','Outras Transferências de Convênio do Estado'); INSERT INTO "revenue_code" VALUES('1.7.2.4.1','Transferências do FUNDEB'); INSERT INTO "revenue_code" VALUES('2.4.2.1.37','Consórcios Públicos'); INSERT INTO "revenue_code" VALUES('1.7.2.2.1.13','Cota-Parte da CIDE - Contribuição de Intervanção no Domínio Econômico'); INSERT INTO "revenue_code" VALUES('2.2.1.2.99','Outras Aplicações de Estoques'); INSERT INTO "revenue_code" VALUES('1.3.6.1.1','Receita de Cessão do Direito de Operacionalização da Folha de Pagamento de Pessoal'); INSERT INTO "revenue_code" VALUES('1.3.6.1.2','Receita de Cessão do Direito de Operacionalização da Folha de Pagamento de Benefícios'); INSERT INTO "revenue_code" VALUES('1.3.6.1.3','Receita de Cessão do Direito de Operacionalização de Pagamento a Fornecedores'); INSERT INTO "revenue_code" VALUES('1.1.2.1.32','Taxa de Aprovação do Projeto de Contrução Civil'); INSERT INTO "revenue_code" VALUES('1.1.2.1.30','Taxa de Autorização de Funcionamento de Transporte'); INSERT INTO "revenue_code" VALUES('1.1.2.1.31','Taxa de Utilização de Área de Domínio Público'); INSERT INTO "revenue_code" VALUES('1.1.2.1.36','Taxa de Apreensão, Depósito ou Liberação de Animais'); INSERT INTO "revenue_code" VALUES('1.1.2.1.34','Taxa de Fiscalização de Aparelhos de Transporte'); INSERT INTO "revenue_code" VALUES('1.1.2.1.35','Taxa de Alinhamento e Nivelamento'); INSERT INTO "revenue_code" VALUES('1.1.1.3.5.2','Adicional ISS - Fundo Municipal de Combate à Pobreza'); INSERT INTO "revenue_code" VALUES('1.1.1.3.5.1','ISS - Imposto sobre Serviços de Qualquer Natureza'); INSERT INTO "revenue_code" VALUES('9.1.3.3.0','Dedução de Receitas de Concessões e Permissões'); INSERT INTO "revenue_code" VALUES('1.7.2.2.22','Transferência da Cota-parte da Compensação Financeira (25%)'); INSERT INTO "revenue_code" VALUES('1.7.2.2.22.11','Cota-Parte da Compensação Financeira de Recursos Hídricos'); INSERT INTO "revenue_code" VALUES('1.3.3.1.99','Outras Receita de Concessões e Permissões - Serviços'); INSERT INTO "revenue_code" VALUES('1.3.2.5.2.2','Remuneração de Aplicação Extramercado'); INSERT INTO "revenue_code" VALUES('1.3.2.5.2.1','Receita de Remuneração de Depósitos de Poupança'); INSERT INTO "revenue_code" VALUES('2.4.7.2.2','Programas de Educação'); INSERT INTO "revenue_code" VALUES('2.4.7.2.3','Programas de Saneamento Básico'); INSERT INTO "revenue_code" VALUES('2.4.7.2.1','Programas de Saúde'); INSERT INTO "revenue_code" VALUES('2.4.7.2.4','Programas de Meio Ambiente'); INSERT INTO "revenue_code" VALUES('2.4.7.2.5','Programas de Infra-Estrutura em Transporte'); INSERT INTO "revenue_code" VALUES('1.5.2.0.12','Receita da Indústria Mecânica'); INSERT INTO "revenue_code" VALUES('1.9.1.9.26','Multas Previstas na Legislação sobre Defesa dos Direitos Difusos'); INSERT INTO "revenue_code" VALUES('1.9.2.2.1','Restituições de Convênios'); INSERT INTO "revenue_code" VALUES('1.9.2.2.2','Restituições de Benefícios não Desembolsados'); INSERT INTO "revenue_code" VALUES('1.7.2.1.1.5','Cota-Parte do ITR - Imposto sobre a Propriedade Territorial Rural'); INSERT INTO "revenue_code" VALUES('1.6.0.0.13.2','Serviços de Venda de Editais'); INSERT INTO "revenue_code" VALUES('1.6.0.0.13.1','Serviços de Inscrição em Concursos Públicos'); INSERT INTO "revenue_code" VALUES('1.6.0.0.13.7','Serviços de Fotocópias e / ou Cópias Heliográficas'); INSERT INTO "revenue_code" VALUES('1.6.0.0.13.6','Serviços de Fornecimento de Listagens'); INSERT INTO "revenue_code" VALUES('1.6.0.0.13.4','Serviços de Expedição de Certificados'); INSERT INTO "revenue_code" VALUES('1.9.3.1.35','Taxas de Fiscalização e Vigilância Sanitária'); INSERT INTO "revenue_code" VALUES('1.7.2.1.22','Transferência da Compensação Financeira pela Exploração de Recursos Naturais'); INSERT INTO "revenue_code" VALUES('1.1.1.0','Impostos'); INSERT INTO "revenue_code" VALUES('2.1.2.3.5','Operações de Crédito Externas para Programas de Modernização da Administração Pública'); INSERT INTO "revenue_code" VALUES('1.1.1.2','Impostos sobre o Patrimônio e a Renda'); INSERT INTO "revenue_code" VALUES('1.1.1.3','Impostos sobre a Produção e a Circulação'); INSERT INTO "revenue_code" VALUES('9.1.7.2.1.1.2','Dedução de Receita para Formação do FUNDEB - FPM'); INSERT INTO "revenue_code" VALUES('9.1.7.2.1.1.5','Dedução de Receita para Formação do FUNDEB - ITR'); INSERT INTO "revenue_code" VALUES('2.4.2.2.37','Consórcios Públicos'); INSERT INTO "revenue_code" VALUES('2.3.0.0','Amortização de Empréstimos'); INSERT INTO "revenue_code" VALUES('1.7.2.1.22.50','Cota-Parte Royalties Pela Participação Especial Lei N° 9.478/97, Artigo 50'); INSERT INTO "revenue_code" VALUES('9.1.3.2.8.10','Dedução da Remuneração dos Investimentos do RPPS em Renda Fixa');

andresmrm commented 9 years ago

Alterei para tirar zeros a direita do primeiro grupo de números quando não houver mas números a direita. Ficou assim a tabela completa: https://gist.github.com/andresmrm/590a9c79342c63cd5dbb