Si te encuentras con algo que te causa duda puedes dejarlo en la sección de comentarios y te responderemos rápidamente.
Solución:
Si puede actualizar a Postgresql 9.5, el jsonb_set
El comando está disponible, como otros han mencionado.
En cada una de las siguientes declaraciones SQL, he omitido el where
cláusula de brevedad; obviamente, querrás volver a agregar eso.
Nombre de actualización:
UPDATE test SET data = jsonb_set(data, 'name', '"my-other-name"');
Reemplace las etiquetas (en oposición a agregar o eliminar etiquetas):
UPDATE test SET data = jsonb_set(data, 'tags', '["tag3", "tag4"]');
Reemplazo de la segunda etiqueta (indexada 0):
UPDATE test SET data = jsonb_set(data, 'tags,1', '"tag5"');
Agregar una etiqueta (esto funcionará siempre que haya menos de 999 etiquetas; cambiar el argumento 999 a 1000 o superior genera un error. Este ya no parece ser el caso en Postgres 9.5.3; se puede utilizar un índice mucho mayor):
UPDATE test SET data = jsonb_set(data, 'tags,999999999', '"tag6"', true);
Eliminar la última etiqueta:
UPDATE test SET data = data #- 'tags,-1'
Actualización compleja (elimine la última etiqueta, inserte una nueva etiqueta y cambie el nombre):
UPDATE test SET data = jsonb_set(
jsonb_set(data #- 'tags,-1', 'tags,999999999', '"tag3"', true),
'name', '"my-other-name"');
Es importante tener en cuenta que en cada uno de estos ejemplos, en realidad no está actualizando un solo campo de los datos JSON. En su lugar, está creando una versión temporal modificada de los datos y asignando esa versión modificada a la columna. En la práctica, el resultado debería ser el mismo, pero tener esto en cuenta debería hacer que las actualizaciones complejas, como el último ejemplo, sean más comprensibles.
En el ejemplo complejo, hay tres transformaciones y tres versiones temporales: Primero, se elimina la última etiqueta. Luego, esa versión se transforma agregando una nueva etiqueta. A continuación, la segunda versión se transforma cambiando el name
campo. El valor en el data
La columna se reemplaza con la versión final.
Idealmente, no usa documentos JSON para datos estructurados y regulares que desea manipular dentro de una base de datos relacional. Utilizar una diseño relacional normalizado en lugar de.
JSON está destinado principalmente a almacenar documentos completos que no necesitan ser manipulados dentro del RDBMS. Relacionado:
- JSONB con indexación frente a hstore
Actualizar una fila en Postgres siempre escribe una nueva versión del entero hilera. Ese es el principio básico del modelo MVCC de Postgres. Desde la perspectiva del rendimiento, poco importa si cambia un solo dato dentro de un objeto JSON o todo: se debe escribir una nueva versión de la fila.
De ahí el consejo del manual:
Los datos JSON están sujetos a las mismas consideraciones de control de simultaneidad que cualquier otro tipo de datos cuando se almacenan en una tabla. Aunque es posible almacenar documentos grandes, tenga en cuenta que cualquier actualización adquiere un bloqueo de nivel de fila en toda la fila. Considere limitar los documentos JSON a un tamaño manejable para disminuir la contención de bloqueos entre las transacciones de actualización. Idealmente, los documentos JSON deberían representar cada uno un datum atómico que dictan las reglas de negocio que no pueden subdividirse razonablemente en datums más pequeños que podrían modificarse de forma independiente.
La esencia de la misma: modificar cualquier cosa dentro de un objeto JSON, debe asignar un objeto modificado a la columna. Postgres proporciona medios limitados para construir y manipular json
datos además de sus capacidades de almacenamiento. El arsenal de herramientas ha crecido sustancialmente con cada nueva versión desde la versión 9.2. Pero el principal sigue siendo: Tú siempre tiene que asignar un objeto modificado completo a la columna y Postgres siempre escribe una nueva versión de fila para cualquier actualización.
Algunas técnicas de cómo trabajar con las herramientas de Postgres 9.3 o posterior:
- ¿Cómo modifico campos dentro del nuevo tipo de datos PostgreSQL JSON?
Esta respuesta ha atraído tantos votos negativos como todas mis otras respuestas en SO juntos. A la gente no parece gustarle la idea: un diseño normalizado es superior para datos no dinámicos. Esta excelente publicación de blog de Craig Ringer explica con más detalle:
- “Antipatrones de PostgreSQL: columnas dinámicas json / hstore innecesarias”
Esto viene en 9.5 en forma de jsonb_set por Andrew Dunstan basado en una extensión existente jsonbx que funciona con 9.4
Acuérdate de que tienes la capacidad de aclarar tu experiencia .