Servidor QGIS enviando UPDATE… WHERE NULL para postgis em uma camada WFS

9

Estou executando um servidor Windows Server 2012.

PostgreSQL 9.3.5, 64 bits

POSTGIS 2.1.3

QGIS Server 2.6.1-2

QGIS Desktop 2.8.3 e 2.12

Estou usando um tablet Microsoft Surface Pro 4 usando o QGIS Desktop 2.12 para editar algumas camadas armazenadas no banco de dados Postgresql. As camadas no tablet são camadas WFS servidas pelo QGIS Server.

Quando eu faço uma edição no Google depois de inserir alguns dados na camada para forçar o envio e o armazenamento dos dados no servidor, às vezes a atualização não está sendo feita no banco de dados.

Percebo que a solicitação http POST chega ao servidor ok, mas às vezes não consigo ver uma confirmação (atualização) no banco de dados e outras vezes ela funciona bem e faz a confirmação.

Nos logs do QGIS Server, posso ver (atualizei os dados de três recursos no QGIS Desktop):

//QGIS SERVER RECEIVED HTTP POST FROM QGIS DESKTOP

[4852][11:11:19] ********************new request*************** [4852][11:11:19] remote ip: 192.168.144.20 [4852][11:11:19] CONTENT_TYPE: text/xml [4852][11:11:19] HTTP_USER_AGENT: Mozilla/5.0 QGIS/2.8.2-Wien [4852][11:11:19] MAP:D:\OSGeo4W\apps\qgis\bin\alumbrado\alumbrado.qgs
[4852][11:11:19] REQUEST:Transaction
[4852][11:11:19] REQUEST_BODY:<Transaction xmlns="http://www.opengis.net/wfs"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.0.0"
service="WFS" xsi:schemaLocation="http://www.qgis.org/gml
http://eudala2.getxo.net/qgis/qgis_mapserv.fcgi.exe?map=D:\OSGeo4W\apps\qgis\bin\alumbrado\alumbrado.qgs&amp;SERVICE=WFS&amp;VERSION=1.0.0&amp;REQUEST=DescribeFeatureType&amp;TYPENAME=getxo_alumbrado_arquetas_registros_cajas&amp;SRSNAME=EPSG:23030"
xmlns:gml="http://www.opengis.net/gml"><Update
xmlns="http://www.opengis.net/wfs"
typeName="getxo_alumbrado_arquetas_registros_cajas"><Property
xmlns="http://www.opengis.net/wfs"><Name
xmlns="http://www.opengis.net/wfs">id_modelo</Name><Value
xmlns="http://www.opengis.net/wfs">0</Value></Property><Property
xmlns="http://www.opengis.net/wfs"><Name
xmlns="http://www.opengis.net/wfs">alumbrado</Name><Value
xmlns="http://www.opengis.net/wfs">t</Value></Property><Filter
xmlns="http://www.opengis.net/ogc"><FeatureId
xmlns="http://www.opengis.net/ogc"
fid="getxo_alumbrado_arquetas_registros_cajas.3"/></Filter></Update><Update
xmlns="http://www.opengis.net/wfs"
typeName="getxo_alumbrado_arquetas_registros_cajas"><Property
xmlns="http://www.opengis.net/wfs"><Name
xmlns="http://www.opengis.net/wfs">id_modelo</Name><Value
xmlns="http://www.opengis.net/wfs">0</Value></Property><Property
xmlns="http://www.opengis.net/wfs"><Name
xmlns="http://www.opengis.net/wfs">alumbrado</Name><Value
xmlns="http://www.opengis.net/wfs">t</Value></Property><Filter
xmlns="http://www.opengis.net/ogc"><FeatureId
xmlns="http://www.opengis.net/ogc"
fid="getxo_alumbrado_arquetas_registros_cajas.4"/></Filter></Update><Update
xmlns="http://www.opengis.net/wfs"
typeName="getxo_alumbrado_arquetas_registros_cajas"><Property
xmlns="http://www.opengis.net/wfs"><Name
xmlns="http://www.opengis.net/wfs">tipo</Name><Value
xmlns="http://www.opengis.net/wfs">A</Value></Property><Property
xmlns="http://www.opengis.net/wfs"><Name
xmlns="http://www.opengis.net/wfs">tipo_tapa</Name><Value
xmlns="http://www.opengis.net/wfs">B</Value></Property><Property
xmlns="http://www.opengis.net/wfs"><Name
xmlns="http://www.opengis.net/wfs">estado</Name><Value
xmlns="http://www.opengis.net/wfs">D</Value></Property><Property
xmlns="http://www.opengis.net/wfs"><Name
xmlns="http://www.opengis.net/wfs">p_tierra_tipo_electrodo_tierra</Name><Value
xmlns="http://www.opengis.net/wfs">O</Value></Property><Property
xmlns="http://www.opengis.net/wfs"><Name
xmlns="http://www.opengis.net/wfs">p_tierra_tipo_union_electrodo_tierra</Name><Value
xmlns="http://www.opengis.net/wfs">N</Value></Property><Property
xmlns="http://www.opengis.net/wfs"><Name
xmlns="http://www.opengis.net/wfs">p_tierra_estado_union_tierra</Name><Value
xmlns="http://www.opengis.net/wfs">D</Value></Property><Property
xmlns="http://www.opengis.net/wfs"><Name
xmlns="http://www.opengis.net/wfs">tipo_intervencion</Name><Value
xmlns="http://www.opengis.net/wfs">OTR</Value></Property><Property
xmlns="http://www.opengis.net/wfs"><Name
xmlns="http://www.opengis.net/wfs">m_codcalle</Name><Value
xmlns="http://www.opengis.net/wfs">20</Value></Property><Property
xmlns="http://www.opengis.net/wfs"><Name
xmlns="http://www.opengis.net/wfs">id_modelo</Name><Value
xmlns="http://www.opengis.net/wfs">0</Value></Property><Property
xmlns="http://www.opengis.net/wfs"><Name
xmlns="http://www.opengis.net/wfs">alumbrado</Name><Value
xmlns="http://www.opengis.net/wfs">t</Value></Property><Filter
xmlns="http://www.opengis.net/ogc"><FeatureId
xmlns="http://www.opengis.net/ogc"
fid="getxo_alumbrado_arquetas_registros_cajas.5"/></Filter></Update></Transaction>
[4852][11:11:19] SERVICE:WFS
[4852][11:11:19] SRSNAME:EPSG:23030
[4852][11:11:19] VERSION:1.0.0
[4852][11:11:22] Request finished in 2977 ms

Ok, quando olho os logs do PostgreSQL, vejo que a atualização possui uma cláusula WHERE NULL, que não atualiza nada.

//POSTGRESQL UPDATE QUERIES
2016-01-29 11:11:22 CET LOG:  00000: sentencia: UPDATE "public"."getxo_alumbrado_arquetas_registros_cajas" SET "id_modelo"=0,"alumbrado"='t' WHERE NULL
2016-01-29 11:11:22 CET UBICACIÓN:  exec_simple_query, src\backend\tcop\postgres.c:890
2016-01-29 11:11:22 CET LOG:  00000: sentencia: UPDATE "public"."getxo_alumbrado_arquetas_registros_cajas" SET "id_modelo"=0,"alumbrado"='t' WHERE NULL
2016-01-29 11:11:22 CET UBICACIÓN:  exec_simple_query, src\backend\tcop\postgres.c:890
2016-01-29 11:11:22 CET LOG:  00000: sentencia: UPDATE "public"."getxo_alumbrado_arquetas_registros_cajas" SET "tipo"='A',"tipo_tapa"='B',"estado"='D',"p_tierra_tipo_electrodo_tierra"='O',"p_tierra_tipo_union_electrodo_tierra"='N',"p_tierra_estado_union_tierra"='D',"tipo_intervencion"='OTR',"m_codcalle"='20',"id_modelo"=0,"alumbrado"='t'
WHERE NULL

Eu posso ver nos dados do POST que o QGIS Server sabe qual recurso precisa ser atualizado usando o número "fid" interno. Minha camada, por outro lado, tem o campo "id" como chave primária. Em algum lugar quando faz o mapeamento do QGIS interno fid para o id da minha camada, ele está se perdendo e adiciona WHERE null à consulta em vez de adicionar where id = 1510.

O engraçado é que eles estão trabalhando há 40 dias e só conseguiram esse problema uma vez, mas desde a semana passada eles têm esse problema todos os dias ... Desde então, às vezes funciona e às vezes não. Reenvio a solicitação http POST do proxy Fiddles do cliente e a mesma postagem HTTP às vezes funciona e outras não.

Eu testei no QGIS Desktop 2.8, 2.10 e 2.12 e acontece em todos eles (o QGIS Server é 2.6.1, eu acho). Eu também testei com diferentes camadas com o mesmo resultado.

Não sei se há algum bug ou se existe algum tipo de configuração na camada que não estou fazendo corretamente no servidor ...


ATUALIZAÇÃO 03/03/2016

Atualizei para o QGIS Server e QGIS Desktop para a 2.12.3 e o problema continua.

Depois de muitos dias de testes, finalmente descobri quando o problema ocorre. Ocorre quando salvo edições da camada no QGIS (via WFS-T) e ao mesmo tempo um mapa Lizmap está sendo carregado por outro usuário. O Lizmap também usa o qgis-server.

Parece que, ao carregar um mapa, o Lizmap deixa o servidor ocupado e, quando uma solicitação de atualização do WFS-T é recebida, o QGIS Server não é capaz de criar a consulta SQL UPDATE corretamente.

Se houver um carregamento do Lizmap no momento em que a postagem do WFS-T for recebida, a consulta do PostgreSQL gerada no qgis-server será:

2016-03-03 11:47:30 CET LOG:  00000: sentencia: UPDATE "public"."getxo_alumbrado_tendido_canalizacion" SET "diametro"='22' WHERE NULL

Por outro lado, se o qgis-server não estiver servindo dados para um Lizmap de carregamento quando o WFS-T chegar, a consulta do PostgreSQL gerada será:

2016-03-03 11:46:21 CET LOG:  00000: sentencia: UPDATE "public"."getxo_alumbrado_tendido_canalizacion" SET "diametro"='111' WHERE "id"::text='1' 

Observe a diferença na cláusula where. O primeiro não faz nada. O segundo funciona bem.

Não sei se posso ajustar o Apache ou qualquer arquivo de configuração do qgis-server para corrigir esse problema.

Tentei dar muito mais hardware ao servidor (4 núcleos e 16 GB de RAM) sem chnage.


Estou fazendo todas as atualizações de software usando o OSGEO4W. Li em algum lugar que os pacotes Apache e PHP não são atualizados há anos. Vou tentar atualizá-los manualmente e verificar se a versão apache ou php não é a causa do problema.


ATUALIZAÇÃO 16/03/2016

Atualizei os pacotes Apache e PHP e o problema continua. Após vários testes, descobri que, se eu salvar alterações de edição (via WFS) enquanto carrego um mapa Lizmap, o salvamento falha, mas outras vezes continuamos falhando, embora não haja carregamento do Lizmap (em volume menor). É um problema no servidor QGIS (qgis_mapserv.fcgi.exe).

Egidi
fonte
Você pode mostrar os logs do servidor QGIS quando funciona? Suponho que eles tenham a mesma aparência, mas precisamos confirmar essa suposição.
21416 alexGIS
@alexGIS Sim, eles são iguais. Eu escrevi uma resposta com a solução para o problema. Obrigado pela ajuda!
Egidi

Respostas:

7

Finalmente, Matthias Kuhn , um dos desenvolvedores do QGIS, me deu a chave.

A cláusula WHERE é criada verificando o tipo da chave primária da tabela. Ele deve ser um inteiro e em algumas das minhas tabelas vi que o tipo era Numérico (8,0).

Essas tabelas e chaves primárias foram criadas por um aplicativo de terceiros há algum tempo.

Alterei o tipo para Inteiro e todos os testes que fiz desde então funcionaram (fiz mais de 100 testes de edição via WFS, na minha opinião, o suficiente para concluir que o problema foi resolvido)

Egidi
fonte