Mais

Encontre duplicatas em um campo e atualize outro campo com um S ou N com Python (ArcGIS)


Estou tentando criar um script python (ArcGIS 10.1) que identificará registros duplicados em um arquivo de forma de pontos com um Y ou N (possibilidade de mais de 5000 registros). Semelhante a este:

xyCombine | duplicar

E836814.148873 N814378.125749 |

E836814.148873 N814378.125749 |

E836815.033548 N814377.614688 |

E836815.033548 N814377.614688 |

E836815.033548 N814377.614688 |

E836818.016542 N814371.411850 |

Desejo processar o campo xyCombine para duplicatas e atualizar outro campo (duplicado) com um S ou N se é uma duplicata ou não. Com o resultado desejado como (não precisa ser classificado):

xyCombine | duplicar

E836814.148873 N814378.125749 | Y

E836814.148873 N814378.125749 | Y

E836815.033548 N814377.614688 | Y

E836815.033548 N814377.614688 | Y

E836815.033548 N814377.614688 | Y

E836818.016542 N814371.411850 | N

Abaixo está minha tentativa:

# Processo: Pesquisa o campo xyCombine para quaisquer duplicatas duplicateCount = 0 inShapefile = pointsShapefile fieldName = "xyCombine" shpFRows = arcpy.UpdateCursor (inShapefile) shpFRow = shpFRows.next () fieldList = [] enquanto shpFRow: if shpFRow.Name) = False e len (str (shpFRow.getValue (fieldName)). Strip ())> 1: fieldList.append (shpFRow.getValue (fieldName)) shpFRow = shpFRows.next () duplicateList = [x para x, y em coleções .Counter (fieldList) .items () if y> 1] print duplicateList selectFile = pointsShapefile selectFields = ('xyCombine', 'dupCHK') shpFRows = arcpy.UpdateCursor (selectFile, selectFields) shpFRow1 = shpFRows.next () enquanto shpFRows.next () enquanto shpFRows.next () if shpFRow1.isNull (fieldName) == False e len (str (shpFRow1.getValue (fieldName)). strip ())> 1: para linha em duplicateList: if shpFRow1.getValue (fieldName) == linha: duplicate + = 1 linha [1] = "Y" else: linha [1] = "N" cursor.updateRow (linha) shpFRow1 = shpFRows.next () if duplicateCount> 0: print "" print "***" + str (duplicado) + "pontos duplicados. ***" impressão ""

Se eu não incluir:

linha [1] = "Y" else: linha [1] = "N" cursor.updateRow (linha)

O script é executado corretamente, imprimindo a quantidade total de duplicatas, no entanto, não atualiza as duplicatas de campo com os valores Y ou N, o que é importante, pois fornecerá um relatório de erro csv posteriormente no script.

No entanto, quando o incluo, recebo a seguinte mensagem de erro:

Python 2.7.2 (padrão, 12 de junho de 2011, 15:08:59) [MSC v.1500 de 32 bits (Intel)] no win32

[u'E836814.148873 N814378.125749 ', u'E836815.033548 N814377.614688', u'E836818.016542 N814371.41185 ']

Traceback (última chamada mais recente): Arquivo "C: Verificação de pontos duplicados Python Scripts DuplicatePointsCheck_TEST1.py", linha 458, em DuplicatePointsCheck () Arquivo "C: Verificação de pontos duplicados Python Scripts DuplicatePointsCheck_TEST1.py", linha 94, na linha DuplicatePointsCheck [1] = "N" TypeError: o objeto 'unicode' não suporta atribuição de item >>>

Eu entendo que existem ferramentas no ArcGIS que fornecerão soluções possíveis por meio da calculadora de campo. No entanto, quero fortalecer minha compreensão do Python, pois sou muito novo no Python. Peço desculpas se essa pergunta foi feita antes, mas eu pesquisei na internet e os únicos resultados da minha pesquisa incluíram localizar e remover registros duplicados.


Depois de várias tentativas (com a sugestão de @Michael Miles-Stimson), tentei simplesmente e remover o código o máximo que pude e descobri o seguinte:

inShapefile = pointsShapefile inShapefileFields = ('xyCombine', 'dplicate') valueList = list () duplicatePointsCount = 0 com arcpy.da.UpdateCursor (inShapefile, inShapefileFields) como cursor: para linha no cursor: if (valueList.count) ])> 1): row [1] = "Y" duplicatePointsCount + = 1 else: row [1] = "N" cursor.updateRow (row) print "" print "***" + str (duplicatePointsCount) + " pontos duplicados. "

No entanto, por algum motivo, não consegui fazer a parte abaixo funcionar e ela continuou a escrever "N" no campo duplicado para todos os registros.

if (valueList.count (row [0])> 1): row [1] = "Y" duplicatePointsCount + = 1

Então tentei o código de @Emil Brundage. E funcionou muito bem!


Seu código parece um pouco complexo para eu decifrar, mas permita-me apresentar um script simplificado que deve cumprir seu objetivo. Ele faz uso de uma inicialSearchCursorpara determinar duplicatas. Ele faz isso preenchendo listas. Ele preenche uma lista de todos os valores que ocorrem uma vez e uma segunda lista de valores que ocorrem mais de uma vez. Em seguida, inicia umUpdateCursorpara preencher seu campo S / N.

from arcpy import * inShapefile = pointsShapefile checkField = "xyCombine" updateField = "dplicate" #List of values ​​found once occurOnce = [] #list of values ​​found two occurTwice = [] cursor = da.SearchCursor (inShapefile, [checkField]) para linha no cursor: #Verificar o valor não é nulo se a linha [0]: #Se ainda não ocorrer duas vezes, prossiga se não a linha [0] em ocorreDuas vezes: #Se ainda não ocorreu uma vez, se não a linha [0] em ocorre uma vez: #Adiciona ocorre uma vez que a lista ocorreOnce.append (linha [0]) #Se o valor já foi encontrado outra vez: #Adiciona ocorre duas vezes lista (duplicatas) ocorreTwice.append (linha [0]) del cursor = da .UpdateCursor (inShapefile, [checkField, updateField]) para linha no cursor: #Check value is not null if row [0]: #check if value in occurTwice list (ie is duplicate) if row [0] in occurTwice: row [ 1] = "Y" else: linha [1] = "N" cursor.updateRow (linha) del cursor

Eu espero que isso ajude!


Você não indica qual versão do arcmap está usando. Se você tiver uma versão avançada, poderá tentar usar a ferramenta Encontrar idêntica.

http://resources.arcgis.com/en/help/main/10.1/index.html#//001700000054000000

Pode ter vários campos, portanto, não há necessidade de concatenar o texto.


Como posso combinar dois ou mais querysets em uma view Django?

Estou tentando construir a busca por um site Django que estou construindo, e nessa busca, procuro em três modelos diferentes. E para obter a paginação na lista de resultados da pesquisa, gostaria de usar uma visão object_list genérica para exibir os resultados. Mas, para fazer isso, preciso mesclar três querysets em um.

Como eu posso fazer isso? Eu tentei isso:

Mas isso não funciona. Recebo um erro quando tento usar essa lista na exibição genérica. A lista não contém o atributo clone.

Como posso mesclar as três listas, page_list, article_list e post_list?


Se você deseja criar uma nova lista de dicionários e deseja mesclá-los removendo duplicatas, isso seria um trabalho simples.

Você pode transformar as listas em strings em dict s digitados pelo nome e, em seguida, atualizar:

Então, se você quiser uma lista de volta, é só

Você menciona classificação em seu título. Se você quiser classificar essa lista por nome:

A primeira coisa a saber é que você não tem dois dicionários diferentes. Voce tem dois diferentes listas de dicionários. A segunda é que você não explica exatamente o que conta como uma duplicata. A terceira é que você não diz o que fazer com a chave de relevância.

Vou assumir que dois dicionários com tipo equivalente e chaves de nome são idênticos e que você deseja que os valores de relevância sejam mesclados em uma lista. Então, mais tarde, você poderia calculá-los, ou o que for.


Outras coisas

Legibilidade, práticas padrão

O código parece pythônico e bom em models.py e view.py, um pouco menos bom no arquivo "front-end" (entrada). Também gostaria de ver alguns testes.

Acho que você documentou um pouco demais, um bom exemplo é:

Eu acho que você pode presumir que a maioria dos leitores saberá o que repr é e faz.

Eu também vi que você só tem três commits em seu repo. Você pode querer trabalhar em seu fluxo de trabalho de controle de versão.

Não acho que você deva permitir qualquer tipo de senha, e acho que você deveria mais do que apenas notificar o usuário que ele selecionou uma senha insegura. Se não quiser forçar senhas estritas, basta pedir que insiram uma senha insegura novamente para confirmar.

Gerenciador de contexto

Eu gosto da ideia de um gerenciador de contexto para suas sessões, mas tome cuidado para lidar com possíveis erros em sua função __exit__.

Comportamento / aviso surpreendente

Na mesma linha, aumente os erros em seu back-end, mas lide com eles você mesmo no front-end, não faça isso:

Reestruturação

Alguns de seus if -clauses deveriam ser elif (ou você poderia refatorar para dicts), e eu preferiria ver seus loops retrabalhados.


Conectando ao servidor MySQL

Nesse ponto, devemos ter o MySQL Community Server configurado em nosso sistema. Agora precisamos escrever algum código em Python que nos permita estabelecer uma conexão com esse servidor.

Uma função para conectar ao nosso servidor MySQL

Criar uma função reutilizável para código como essa é a prática recomendada, para que possamos usá-la repetidamente com o mínimo de esforço. Depois de escrito, você poderá reutilizá-lo em todos os seus projetos no futuro também, portanto, no futuro, você será grato!

Vamos repassar linha por linha para entender o que está acontecendo aqui:

A primeira linha é nós nomeando a função (create_server_connection) e nomeando os argumentos que essa função terá (host_name, user_name e user_password).

A próxima linha fecha todas as conexões existentes para que o servidor não se confunda com várias conexões abertas.

Em seguida, usamos um bloco try-except do Python para lidar com quaisquer erros em potencial. A primeira parte tenta criar uma conexão com o servidor usando o método mysql.connector.connect () usando os detalhes especificados pelo usuário nos argumentos. Se funcionar, a função imprime uma pequena mensagem feliz de sucesso.

A parte exceto do bloco exibe o erro que o MySQL Server retorna, na infeliz circunstância de haver um erro.

Finalmente, se a conexão for bem-sucedida, a função retorna um objeto de conexão.

Usamos isso na prática atribuindo a saída da função a uma variável, que então se torna nosso objeto de conexão. Podemos então aplicar outros métodos (como cursor) a ele e criar outros objetos úteis.

Aqui, pw é uma variável que contém a senha root para nosso servidor MySQL como uma string.

Isso deve produzir uma mensagem de sucesso:

Viva!

Criação de um novo banco de dados

Agora que estabelecemos uma conexão, nosso próximo passo é criar um novo banco de dados em nosso servidor.

Neste tutorial, faremos isso apenas uma vez, mas novamente escreveremos isso como uma função reutilizável, portanto, temos uma função útil e agradável que podemos reutilizar em projetos futuros.

Esta função leva dois argumentos, conexão (nosso objeto de conexão) e consulta (uma consulta SQL que escreveremos na próxima etapa). Ele executa a consulta no servidor por meio da conexão.

Usamos o método cursor em nosso objeto de conexão para criar um objeto cursor (MySQL Connector usa um paradigma de programação orientado a objetos, portanto, há muitos objetos herdando propriedades de objetos pais).

Este objeto cursor possui métodos como execute, executemany (que usaremos neste tutorial) junto com vários outros métodos úteis.

Se ajudar, podemos pensar no objeto cursor como fornecendo acesso ao cursor piscante em uma janela de terminal do servidor MySQL.

Você sabe, este.

Em seguida, definimos uma consulta para criar o banco de dados e chamar a função:

Todas as consultas SQL usadas neste tutorial são explicadas em minha série de tutoriais de Introdução ao SQL, e o código completo pode ser encontrado no Jupyter Notebook associado neste repositório GitHub, portanto, não fornecerei explicações sobre o que o código SQL faz neste tutorial.

No entanto, esta talvez seja a consulta SQL mais simples possível. Se você consegue ler em inglês, provavelmente pode descobrir o que ele faz!

Executar a função create_database com os argumentos acima resulta em um banco de dados chamado 'school' sendo criado em nosso servidor.

Por que nosso banco de dados é chamado de 'escola'? Talvez agora seja um bom momento para examinar com mais detalhes o que exatamente iremos implementar neste tutorial.

Nosso banco de dados

O diagrama de relacionamento de entidades para nosso banco de dados.

Seguindo o exemplo da minha série anterior, vamos implementar o banco de dados da International Language School - uma escola fictícia de treinamento de idiomas que oferece aulas de idiomas profissionais para clientes corporativos.

Este Diagrama de Relacionamento de Entidades (ERD) apresenta nossas entidades (Professor, Cliente, Curso e Participante) e define as relações entre elas.

Todas as informações sobre o que é um ERD e o que considerar ao criar um e projetar um banco de dados podem ser encontradas neste artigo.

O código SQL bruto, os requisitos do banco de dados e os dados para entrar no banco de dados estão todos contidos neste repositório GitHub, mas você verá tudo ao longo deste tutorial também.

Conectando-se ao banco de dados

Agora que criamos um banco de dados no servidor MySQL, podemos modificar nossa função create_server_connection para conectar diretamente a este banco de dados.

Observe que é possível - comum, na verdade - ter vários bancos de dados em um servidor MySQL, portanto, queremos nos conectar sempre e automaticamente ao banco de dados no qual estamos interessados.

Esta é exatamente a mesma função, mas agora pegamos mais um argumento - o nome do banco de dados - e passamos isso como um argumento para o método connect ().

Criação de uma função de execução de consulta

A função final que vamos criar (por enquanto) é extremamente vital - uma função de execução de consulta. Isso vai pegar nossas consultas SQL, armazenadas em Python como strings, e passá-las para o método cursor.execute () para executá-las no servidor.

Esta função é exatamente igual à função create_database anterior, exceto que usa o método connection.commit () para garantir que os comandos detalhados em nossas consultas SQL sejam implementados.

Essa será nossa função burra de carga, que usaremos (junto com create_db_connection) para criar tabelas, estabelecer relacionamentos entre essas tabelas, preencher as tabelas com dados e atualizar e excluir registros em nosso banco de dados.

Se você for um especialista em SQL, esta função permitirá que você execute todos e quaisquer comandos e consultas complexas que possa ter por aí, diretamente de um script Python. Esta pode ser uma ferramenta muito poderosa para gerenciar seus dados.


Como posso mesclar um Excel com milhares de registros de código postal (sem latitude / longitude) com um arquivo de forma de centróide de código postal com latitude / longitude?

Estou executando um teste de amostra para um conjunto de dados muito maior. Recebi uma planilha Excel com 3.000 registros com CEPs (e outros dados), mas nenhum outro identificador geoespacial. Estou tentando criar um arquivo de forma a partir disso.

No entanto, eu & # x27m encontrando um problema devido à grande quantidade de CEPs duplicados. Eu & # x27m estou achando difícil & quotassociar & quot com um arquivo de forma de centróide com código postal (com latitude / longitude) que & # x27criei.

É possível, e em caso afirmativo, como, mesclar / juntar o arquivo de forma do CEP do centroide e preencher automaticamente a planilha do Excel com a latitude / longitude associada, mantendo os CEPs duplicados? Em seguida, exportar esse resultado para seu próprio arquivo de forma? Por exemplo, O resultado unido mostraria os 3.000 registros, com os códigos postais duplicados, mas agora tem a latitude / longitude associada a ele para que possa ser mapeado e analisado?


Resumo

Isso conclui nosso blog. Na primeira parte, expliquei quatro das seis etapas para construir nossa solução de amostra. Compartilhei informações valiosas sobre Exportar sub-rede e como baixar e analisar o retorno JSON da ferramenta. Nesta segunda parte, concluímos o exemplo com as duas últimas etapas e discutimos a saída JSON da sub-rede de exportação em detalhes, trabalhando com o serviço de recursos de sua rede de utilitários e seus elementos de dados, criação de recursos incluindo geometria de JSON e alteração de domínios codificados para descrições fáceis de usar e gravação dinâmica para várias saídas. No geral, mostrei como construir uma ferramenta de automação de sub-rede de exportação usando a extensão de interoperabilidade de dados do ArcGIS Pro. Por último, mostrei como executar e configurar bancadas de trabalho parametrizadas e como usar a caixa de ferramentas Spatial ETL no Pro. Este arquivo de ambiente de trabalho agora está pronto para automação adicional para exportar todas as sub-redes de qualquer rede de utilidade & # 8230, que será o tópico do meu próximo blog.

Espero que você tenha chegado até aqui e tenha achado o blog informativo e útil. Deixe comentários abaixo com quaisquer perguntas sobre o exemplo fornecido ou com a própria Exportação de sub-rede.

Imagens de cartão e banner por:


Como pesquisar rapidamente em uma lista muito grande de strings / registros em um banco de dados

Estou com o seguinte problema: tenho um banco de dados que contém mais de 2 milhões de registros. Cada registro tem um campo de string X e desejo exibir uma lista de registros para os quais o campo X contém uma determinada string. Cada registro tem cerca de 500 bytes de tamanho.

Para tornar isso mais concreto: na GUI do meu aplicativo, tenho um campo de texto onde posso inserir uma string. Acima do campo de texto, tenho uma tabela exibindo os (primeiros N, por exemplo, 100) registros que correspondem à string no campo de texto. Quando eu digito ou excluo um caractere no campo de texto, o conteúdo da tabela deve ser atualizado imediatamente.

Gostaria de saber se existe uma maneira eficiente de fazer isso usando estruturas de índice apropriadas e / ou cache. Conforme explicado acima, desejo exibir apenas os primeiros N itens que correspondem à consulta. Portanto, para N pequenos o suficiente, não deve ser um grande problema carregar os itens correspondentes do banco de dados. Além disso, armazenar itens em cache na memória principal pode tornar a recuperação mais rápida.

Acho que o principal problema é como encontrar os itens correspondentes rapidamente, dada a string do padrão. Posso contar com alguns recursos do DBMS ou tenho que construir algum índice na memória sozinho? Alguma ideia?

Eu fiz uma primeira experiência. Eu dividi os registros em arquivos de texto diferentes (no máximo 200 registros por arquivo) e coloquei os arquivos em diretórios diferentes (usei o conteúdo de um campo de dados para determinar a árvore de diretórios). Acabei com cerca de 50.000 arquivos em cerca de 40.000 diretórios. Em seguida, executei o Lucene para indexar os arquivos. Pesquisar uma string com o programa de demonstração Lucene é muito rápido. A divisão e a indexação demoraram alguns minutos: isso é totalmente aceitável para mim porque é um conjunto de dados estáticos que desejo consultar.

A próxima etapa é integrar o Lucene no programa principal e usar os acessos retornados pelo Lucene para carregar os registros relevantes na memória principal.


Uma boa maneira de fazer essa comparação é usar find com md5sum e, em seguida, um diff.

Use find para listar todos os arquivos no diretório, em seguida, calcule o hash md5 para cada arquivo e canalize-o classificado por nome de arquivo para um arquivo:

Faça o mesmo procedimento para o outro diretório:

Em seguida, compare o resultado de dois arquivos com diff:

Ou como um único comando usando substituição de processo:

Se você quiser ver apenas as mudanças:

O comando cut imprime apenas o hash (primeiro campo) a ser comparado por diff. Caso contrário, diff irá imprimir todas as linhas, pois os caminhos do diretório são diferentes mesmo quando o hash é o mesmo.

Mas você não saberá qual arquivo foi alterado.

Para isso, você pode tentar algo como

Esta estratégia é muito útil quando os dois diretórios a serem comparados não estão na mesma máquina e você precisa ter certeza de que os arquivos são iguais em ambos os diretórios.

Outra boa maneira de fazer o trabalho é usar o comando diff do Git (pode causar problemas quando os arquivos têm permissões diferentes -> cada arquivo é listado na saída então):


18 Respostas 18

Se você não pode usar uma das muitas ferramentas que existem por causa de problemas de conectividade e deseja uma comparação "offline", você pode usar o SSMS para gerar scripts para todos os objetos de banco de dados clicando com o botão direito no banco de dados e usando "Tarefas. / Gerar Scripts" e certifique-se de selecionar a criação de um arquivo por objeto.

Quando você tiver feito isso para os dois bancos de dados, coloque os dois conjuntos de scripts em uma máquina local em duas pastas separadas e use o WinMerge (ou similar) para comparar os dois.

Depois de me esforçar para encontrar uma maneira fácil de fazer a mesma tarefa - veja o que mudou entre 2 modelos, escrevi o seguinte script SQL que comparará dois esquemas para determinar colunas novas e excluídas

Outra opção é usar o SQL Server Data Tools (SSDT), uma extensão do Visual Studio. Você pode extrair o esquema do banco de dados como um arquivo .dacpac e compará-lo com outro arquivo .dacpac ou um banco de dados existente. O SSDT está incluído nas ferramentas de cliente do SQL Server 2012, tornando-o bastante acessível. Você pode encontrar as instruções completas sobre como executar a comparação no site do MSDN.

Faça uma pesquisa por "SQL Server Compare" e você encontrará muitas ferramentas. O que usamos no meu trabalho é o Red Gate SQLCompare. Tem um período de teste de 14 dias. Mas como você está falando de dois ambientes diferentes, não acho que isso funcionaria para você, a menos que o cliente envie um backup do banco de dados dele. A outra opção é escrever consultas nas tabelas do sistema (como sys.indexes, sys.tables, etc).

Talvez este script gratuito https://github.com/dlevsha/compalex possa ajudá-lo. Suporta Microsoft SQL Server.

Compalex é um script leve e gratuito para comparar dois esquemas de banco de dados. Suporta MySQL, MS SQL Server e PostgreSQL.

Se você precisar comparar mais de um arquivo de banco de dados, poderá fazer o script SQLPackage.exe.

Não tenho o código funcionando para você, mas você pode olhar a documentação do SQLPackage.exe para se inspirar.

Você extrairia seu banco de dados mestre para um arquivo dacpac e, em seguida, compararia o arquivo dacpac com o restante de seus bancos de dados. O resultado da comparação pode ser um relatório xml das alterações ou um arquivo .sql que você pode executar para sincronizar os bancos de dados.

Você pode consultar este artigo ou este para obter um exemplo de código.

Eu tinha exatamente a mesma dúvida e acredito que o Microsoft SQL Server Management Studio (SSMS) tem uma solução muito mais fácil / simples do que qualquer coisa que vi aqui. Tenho um site de produção com MS SQL Server Express e em breve haveria vários outros onde não quero ter que instalar o VisualStudio ou outros aplicativos além do SSMS.

Portanto, no SSMS, clique com o botão direito do mouse no banco de dados para obter o esquema. Selecione Tarefas> Gerar scripts. para abrir um assistente para criar um script de esquema e configuração para todo o banco de dados (ou objetos selecionados, se desejar). Eu mantive todas as opções padrão, exceto o caminho / nome do arquivo, mas a ferramenta tem uma infinidade de opções. O assistente criou um SQL que copiei via OneDrive de volta para o meu PC. Em seguida, usei o Notepad ++ para comparar o SQL a um arquivo gerado da mesma maneira em relação ao meu banco de dados SIT. Você tem que filtrar as ocorrências de data / hora nos comentários, mas caso contrário, é uma ótima comparação entre os dois bancos de dados.

Presto! Escrever isso foi significativamente mais difícil do que fazer a comparação real.

A maneira mais fácil é usar uma ferramenta automatizada construída para este propósito, mas se você não tiver acesso a um, poderá obter todas as informações básicas de que precisa nas visualizações INFORMATION_SCHEMA.

Usar os metadados em INFORMATION_SCHEMA é provavelmente uma opção mais fácil do que gerar scripts DDL e fazer uma comparação de origem, porque você tem muito mais controle sobre como os dados são apresentados. Você não pode realmente controlar a ordem em que os scripts gerados apresentarão os objetos em um banco de dados. Além disso, os scripts contêm um monte de texto que pode ser dependente da implementação por padrão e pode causar muito "ruído" de incompatibilidade quando o que você provavelmente realmente precisa se concentrar é uma tabela, visão ou coluna ausente ou possivelmente um tipo de dados de coluna ou incompatibilidade de tamanho.

Escreva uma consulta (ou consultas) para obter as informações importantes para o seu código nas visualizações INFORMATION_SCHEMA e execute-as em cada SQL Server a partir do SSMS. Você pode então despejar os resultados em um arquivo e usar uma ferramenta de comparação de arquivos de texto (até mesmo o MS Word) ou pode despejar os resultados em tabelas e executar consultas SQL para encontrar incompatibilidades.

Estou incluindo esta resposta por causa de uma nova pergunta que foi marcada como uma duplicata.

Certa vez, tive que comparar dois bancos de dados de produção e encontrar qualquer diferença de esquema entre eles. Os únicos itens de interesse foram as tabelas que foram adicionadas ou eliminadas e as colunas que foram adicionadas, removidas ou alteradas. Não tenho mais os scripts SQL que desenvolvi, mas o que segue é a estratégia geral. E o banco de dados não era SQL Server, mas acho que a mesma estratégia se aplica.

Primeiro, criei o que pode ser melhor descrito como um metadatabase. As tabelas do usuário deste banco de dados continham descrições de dados copiadas das tabelas do sistema dos bancos de dados de produção. Coisas como nome da tabela, nome da coluna, tipo de dados e precisão. Havia mais um item, Nome do banco de dados, que não existia em nenhum dos bancos de dados de produção.

Em seguida, desenvolvi scripts que combinavam seleções das tabelas de sistema dos bancos de dados de produção com inserções nas tabelas de usuário do metadatabase.

Finalmente, desenvolvi consultas para encontrar tabelas que existiam em um banco de dados, mas não o outro, e colunas de tabelas em ambos os bancos de dados que estavam em apenas um banco de dados e colunas com definições inconsistentes entre os dois bancos de dados.

Em cerca de 100 tabelas e 600 colunas, encontrei um punhado de inconsistências e uma coluna que foi definida como um ponto flutuante em um banco de dados e um inteiro no outro. Esse último acabou sendo uma dádiva de Deus, porque revelou um problema que vinha atormentando um dos bancos de dados há anos.

O modelo da metadatabase foi sugerido pelas tabelas do sistema em questão. As consultas não foram difíceis de construir, girando principalmente em torno de group by e tendo count (nome do banco de dados) = 1.

No seu caso, com 700 bancos de dados de produção, você pode querer automatizar as duas primeiras etapas mais do que fiz com apenas dois bancos de dados para comparar. Mas a ideia é semelhante.


Assista o vídeo: Python for Geographers (Outubro 2021).