Mais

Depuração RuntimeError: espaço de trabalho já no modo de transação das classes de recursos arcpy.da.UpdateCursor e ArcSDE?

Depuração RuntimeError: espaço de trabalho já no modo de transação das classes de recursos arcpy.da.UpdateCursor e ArcSDE?


Estou fazendo minha primeira tentativa de editar uma classe de recurso ArcSDE com python por meio de um da.UpdateCursor. Basicamente, estou pegando o código que escrevi para uma classe de recurso de banco de dados geográfico de arquivo e aplicando-o a uma classe de recurso SDE. Isso produz um erro e não tenho certeza de como retificar o problema.

Estou usando ArcGIS 10.1 para Desktop.

Código pertinente:

Struxfeature = r "DatabaseConnections  PipelinePathways.sde  PPGIS.Strux  PPGIS.StruxPts_v04_all" P6feature = r "DatabaseConnections  PipelinePathways.sde  PPGIS.Strux  PPGIS.Land_Projects_Parcels_P6" SDE = r "Conexões de banco de dados" Pipeline.sde E1B8 "Parent =" SDE.DEFAULT "version =" change_RW_VC_4447_14_to_C "#Create Version print" Criando versão "arcpy.CreateVersion_management (SDE, Parent, version," PUBLIC ") VersionName = UserID.upper () +". " + version #Layers arcpy.MakeFeatureLayer_management (Struxfeature, "Struxlyr") arcpy.MakeFeatureLayer_management (P6feature, "P6lyr") #Switch to version print "Switching version" arcpy.ChangeVersion_management ("Struxlyr_management_Version") ("P6lyr", "TRANSACTIONAL", VersionName) #Iniciar edição imprimir "Iniciando edição" edit = arcpy.da.Editor (SDE) edit.startEditing () # Iniciar uma operação de edição edit.startOperation () #Change P6 project numbers print "Atualizando P6.  N" P6Cursor = arcpy.da.UpdateCursor ("P6lyr", ["P6_NBR", "Nome"]) para linha em P6Cursor: codecodecode

O erro vem da linha 'para linha em P6Cursor:'

Traceback (última chamada mais recente): Arquivo "C:  E1B8  ScriptTesting  ScriptsIUse  ChangeP6.py", linha 81, em  para linha em P6Cursor: RuntimeError: espaço de trabalho já em modo de transação

Com ajuda, encontrei minha solução, embora o raciocínio por trás dela seja um pouco confuso atualmente. No meu código, criar uma versão por meio de um arquivo de conexão SDE e, em seguida, criar a camada de feição a ser editada por meio de outro arquivo de conexão SDE que está conectado à nova versão funciona. Além disso, edit.startEditing deve ter a variável 'multiuser_mode' definida como true (o padrão). Pelo que entendi, esta variável indica se pode haver várias versões / usuários permitidos para a camada. Como isso sempre é verdadeiro para uma camada de feição SDE, definir essa variável como False causa um erro.

Código de funcionamento, onde testo um cursor de atualização:

import arcpy import os #Locals P6featureName = r "PPGIS.Strux  PPGIS.Land_Projects_Parcels_P6" Parent = "SDE.DEFAULT" version = "SDE_Test" Server = *** Service = *** user = *** Pass = *** SDE = "Database Connections  PipelinePathways.sde" temploc = r "C:  E1B8  ScriptTesting  Workspace" fil = "SDETempConn" env.overwriteOutput = True #Create Version print "Criando versão" arcpy.CreateVersion_management (SDE, Parent, version , "PUBLIC") VersionName = user.upper () + "." + versão #Create new connection workspace = os.path.join (temploc, fil + ".sde") print "Criando conexão SDE" arcpy.CreateArcSDEConnectionFile_management (temploc, fil, Server, Service, username = user, password = Pass, version = VersionName) #Layers P6feature = os.path.join (workspace, P6featureName) arcpy.MakeFeatureLayer_management (P6feature, "P6lyr") #Start edition print "Iniciando edição" edit = arcpy.da.Editor (workspace) edit.startEditing () edit.startOperation () #Test Cursor print "Cursor de teste" P6Cursor = arcpy.da.UpdateCursor ("P6lyr", ["NAME"]) para linha em P6Cursor: imprimir linha [0] del row del P6Cursor # Parar / salvar edições edit.stopOperation () print "Parando a edição" edit.stopEditing ("True") #Switch to version print "Trocando a versão" arcpy.ChangeVersion_management ("P6lyr", "TRANSACTIONAL", Parent) #Reconcile and post print "Reconciliando e postando "arcpy.ReconcileVersions_management (workspace," ", Parent, VersionName, with_post =" POST ", with_delete =" DELETE_VERSION ")

Obrigado a Ben Nadler pela ajuda.


No meu caso, a tabela que estávamos inserindo não estava registrada no geodatabase e nunca seria registrada. Adicionar uma chave primária e coluna de identidade resolveu esse problema para nós.


Eu tive o mesmo problema: "espaço de trabalho já em modo de transação". Eu tinha um banco de dados Microsoft SQL Server conectado ao ArcCatalog como SDE.

E a decisão no meu caso foi apenas alterar o tipo de coluna "timestamp" da tabela de destino para "imagem".


Eu também tive esse erro no meu script python ao adicionar novas camadas de recursos. Depois de perder muito tempo percebi que as camadas não estavam registradas. Então, registrei as camadas e fiz com que funcionassem.


Melhor usar Python ou R para pesquisar registros em uma tabela muito grande para recursos correspondentes no FGDB?

EDIT: Estou tentando encontrar a melhor solução e, embora só esteja familiarizado com Python, o que estou tentando fazer não deve ser tão difícil ou demorar tanto. Eu editei o título para perguntar sobre opções usando R ou outros programas.

Estou trabalhando no seguinte desafio no ArcGIS 10.1 em um computador de 64 bits com Python 2.7.

Tenho uma tabela com três campos: ID #, "Revenue" e "Live" - e 2,1 milhões de registros.

Estou tentando obter classes de recursos de um fGDB combinando seu nome com o ID # nesta tabela, adicionar dois campos ao FC e preencher esses campos com receita e valor de dados Live.

Meu script inclui camadas e camadas de loops for, instruções if e cursores de pesquisa. Embora tenha funcionado em um pequeno lote de teste, está demorando uma eternidade com os dados reais, porque está pesquisando 2,1 milhões de registros.

Incluí meu script abaixo, que funciona - e também mostra meu fluxo lógico, que é onde preciso de orientação.

Qual é a melhor estratégia ao comparar / combinar uma lista muito longa de registros com um conjunto de classes de recursos?


Vjylku

Como resolver uma equação diferencial com um termo para uma potência?

Qual tubo vai caber em uma roda - (700 x 25c)?

Torna eclipses solares extremamente raros, mas ainda têm luas novas

Posso equipar Skullclamp em uma criatura que estou sacrificando?

Soma não determinística de flutuações

Por que tenho permissão para criar vários ponteiros exclusivos de um único objeto?

Se / quando o Reino Unido deixar a UE, um futuro governo pode realizar um referendo para aderir à UE?

Diferentes mudanças harmônicas implícitas em uma escala decrescente simples

Se a pilha foi inicializada para segurança, por que a pilha não foi inicializada?

Por que a notação padrão não preserva os intervalos (visualmente)

Como evitar supervisores com visões preconceituosas?

Por que Khan não ressuscitou na explosão de Gênesis?

O que é (CFMCC) no gráfico de abordagem ILS?

É gramatical "para causar autismo em X"?

HostGator está armazenando minha senha em texto simples?

Magia não confiável - vale a pena?

Existe um análogo de espaços projetivos para esquemas adequados?

Você pode substituir um traço racial que pode falhar ao subir de nível?

Criando um novo campo no shapefile usando ArcPy?

Eu sou novo em scripts e em Python / arcpy. Minha intenção com este script é:


  • selecione pontos de uma classe de recursos que se enquadrem em um polígono alvo e que atendam a uma consulta de atributo especificada pela variável 'amenidades'.
  • crie três novas classes de recursos desses pontos.
  • adicione um novo campo de texto a cada uma das classes de recursos.
  • atualize esse campo.

Estou preso na etapa em que adicionaria o novo campo a cada nova classe de recurso e atualizaria o cursor.

cursor.updateRow () recebe uma sequência, mas você está alimentando um único valor. Tente cursor.updateRow ([dataSource]). Se não funcionar depois disso, precisaremos da mensagem de erro real que você está suprimindo com o bloco try / except. É geralmente uma má prática usar blocos try / except "nus", uma vez que isso oculta qualquer erro real que esteja ocorrendo, seja ele esperado ou não, e esses rastreamentos são essenciais para depuração.

Eu sou novo em scripts e em Python / arcpy. Minha intenção com este script é:


  • selecione pontos de uma classe de recursos que se enquadram em um polígono alvo e que atendem a uma consulta de atributo especificada pela variável 'amenidades'.
  • crie três novas classes de recursos desses pontos.
  • adicione um novo campo de texto a cada uma das classes de recursos.
  • atualize esse campo.

Estou preso na etapa em que adicionaria o novo campo a cada nova classe de recurso e atualizaria o cursor.

cursor.updateRow () leva uma sequência, mas você está alimentando em um único valor. Tente cursor.updateRow ([dataSource]). Se não funcionar depois disso, precisaremos da mensagem de erro real que você está suprimindo com o bloco try / except. É geralmente uma má prática usar blocos try / except "nus", uma vez que isso oculta qualquer erro real que esteja ocorrendo, seja ele esperado ou não, e esses rastreamentos são essenciais para depuração.

Eu sou novo em scripts e em Python / arcpy. Minha intenção com este script é:


  • selecione pontos de uma classe de recursos que se enquadrem em um polígono alvo e que atendam a uma consulta de atributo especificada pela variável 'amenidades'.
  • crie três novas classes de recursos desses pontos.
  • adicione um novo campo de texto a cada uma das classes de recursos.
  • atualize esse campo.

Estou preso na etapa em que adicionaria o novo campo a cada nova classe de recurso e atualizaria o cursor.

Eu sou novo em scripts e em Python / arcpy. Minha intenção com este script é:


  • selecione pontos de uma classe de recursos que se enquadram em um polígono alvo e que atendem a uma consulta de atributo especificada pela variável 'amenidades'.
  • crie três novas classes de recursos desses pontos.
  • adicione um novo campo de texto a cada uma das classes de recursos.
  • atualize esse campo.

Estou preso na etapa em que adicionaria o novo campo a cada nova classe de recurso e atualizaria o cursor.


18 Respostas 18

Pelo que me lembro no Windows, a ordem de pesquisa por uma dll é:

  1. Diretório atual
  2. Pasta do sistema, C: windows system32 ou c: windows SysWOW64 (para processo de 32 bits na caixa de 64 bits).
  3. Leitura da variável de ambiente Path

Além disso, eu verificaria as dependências da DLL, o dependencywalker fornecido com o Visual Studio pode ajudá-lo aqui, ele também pode ser baixado gratuitamente: http://www.dependencywalker.com

Você pode usar a ferramenta dumpbin para descobrir as dependências DLL necessárias:

Isso informará quais DLLs sua DLL precisa carregar. Particularmente, preste atenção ao MSVCR * .dll. Eu vi seu código de erro ocorrer quando o Visual C ++ Redistributable correto não está instalado.

Você pode obter os "Pacotes redistribuíveis do Visual C ++ para Visual Studio 2013" no site da Microsoft. Ele instala c: windows system32 MSVCR120.dll

No nome do arquivo, 120 = 12.0 = Visual Studio 2013.

Tenha cuidado para ter a versão certa do Visual Studio (10.0 = VS 10, 11 = VS 2012, 12.0 = VS 2013.) arquitetura certa (x64 ou x86) para a plataforma de destino de sua DLL e também deve ser cuidadoso com as compilações de depuração . A compilação de depuração de uma DLL depende do MSVCR120d.dll, que é uma versão de depuração da biblioteca instalada com o Visual Studio, mas não pelo pacote redistribuível.

Este é um 'kludge' mas você poderia pelo menos usá-lo para um teste de sanidade: tente codificar o caminho para a DLL em seu código

Dito isso, no meu caso, executando dumpbin / DEPENDENTS conforme sugerido por @antony-hayward, e copiando 32 bits versões das DLLs listadas lá em meu diretório de trabalho resolveram esse problema para mim.

A mensagem é um pouco enganosa, porque não é "minha" dll que não pode ser carregada - são as dependências

A DLL deve estar na pasta bin.

No Visual Studio, adiciono a dll ao meu projeto NÃO nas referências, mas em & quotAdicionar arquivo existente & quot. Em seguida, defina a propriedade & quotCopy para Output Directory & quot da dll como & quotCopy if newer & quot.

Tente inserir o caminho completo da dll. Se não funcionar, tente copiar a dll para a pasta system32.

Certifique-se de que todas as dependências de sua própria dll estejam presentes perto da dll ou no System32.

Ative o registro de fusão, veja esta pergunta para muitos conselhos sobre como fazer isso. Depurar problemas de carregamento de aplicativos de modo misto pode ser uma verdadeira dor de cabeça. O registro de fusão pode ser uma grande ajuda.

Há uma coisa muito engraçada (e de relevância técnica) que pode desperdiçar suas horas, então pensei em compartilhá-la aqui -

Eu criei um projeto de aplicativo de console ConsoleApplication1 e um projeto de biblioteca de classes ClassLibrary1.

Todo o código que estava fazendo o p / invoke estava presente em ClassLibrary1.dll. Portanto, antes de depurar o aplicativo do visual studio, simplesmente copiei o assembly não gerenciado C ++ (myUnmanagedFunctions.dll) para o diretório bin debug do projeto ClassLibrary1 para que ele possa ser carregado em tempo de execução pelo CLR.

erro por horas. Mais tarde, percebi que todos os assemblies não gerenciados que devem ser carregados precisam ser copiados para o diretório bin debug do projeto de inicialização ConsoleApplication1, que geralmente é um formulário win, console ou aplicativo da web.

Portanto, tenha cuidado, pois o diretório atual na resposta aceita significa, na verdade, o diretório atual do executável principal de onde o processo de inscrição está começando. Parece algo óbvio, mas às vezes pode não ser.

Lição aprendida - Sempre coloque as dlls não gerenciadas no mesmo diretório do executável de inicialização para garantir que possam ser encontradas.


Assista o vídeo: Four Advanced Field Calculator Tricks