splor-mg / dados-sigplan-planejamento

Conjunto de dados do PPAG Planejamento
0 stars 0 forks source link

Explorar comportamento de `make infer` quando existe alterações (incluindo nomes) dos arquivos primários #9

Open fjuniorr opened 1 year ago

fjuniorr commented 1 year ago

Eu removi o script antigo de inferência dos tables schemas (#8) no commit https://github.com/splor-mg/ppag-planejamento-dados/commit/1d2a0d5639caa726c513eecabcf56727b54da777.

No entanto, as alterações no schema nas bases da LOA entre 2023 e 2024 confirmaram a utilidade de uma interface para fazer inferência automática de schemas e que ajude também na comparação entre schemas que deveriam ser iguais.

Uma possível implementação que adiciona alguns valores de exemplo no schema:

fields:
  - name: UO_COD
    type: integer
    examples:
      - '1011'
      - '1011'
      - '1011'
      - '1011'
      - '1021'
      - '9901'
      - '9901'
      - '9901'
      - '9901'
      - '9901'

seria

import typer
from frictionless import Package, Resource
import petl as etl
from pathlib import Path

def infer(resource_name: str, output_path: Path = '.', descriptor: str = 'datapackage.yaml', examples: bool = True):
    package = Package(descriptor)
    resource = package.get_resource(resource_name)

    descriptor_infer = {'name': resource.name, 
                        'path': resource.path, 
                        'format': resource.format, 
                        'type': resource.type, 
                        'encoding': resource.encoding}
    resource_infer = Resource.from_descriptor(descriptor_infer, dialect = resource.dialect)
    resource_infer.infer()
    if examples:
        for field in resource_infer.schema.fields:
            data = resource_infer.read_cells()
            data = etl.cut(data, field.name)
            head = etl.head(data)
            tail = etl.tail(data)
            examples = etl.cat(head, tail)
            field.custom['examples'] = [row[field.name] for row in etl.dicts(examples)]
            # the example property exists in the spec https://specs.frictionlessdata.io/table-schema/#example
            # however, I think it's value is validated against the field valid values
            # field.example = [row[field.name] for row in etl.dicts(examples)]
            # field-error - Provided field is not valid.
    resource_infer.schema.to_yaml(Path(output_path, f'{resource_name}.yaml'))
    return 0

if __name__ == '__main__':
    typer.run(infer)

Para executar os dados primários já devem estar disponíveis e devidamente documentados no datapackage.yaml

python scripts/infer.py base_orcam_receita_fiscal