2012-10-01 23 views
8

Tengo que importar datos sin información de zona horaria (sin embargo, conozco la zona horaria específica de los datos que deseo importar), pero necesito el formato timestamp with time zone en la base de datos. Una vez que lo importe y establezca el tipo de datos de marca de tiempo en timestamp with time zone, Postgres asumirá automáticamente que los datos en la tabla pertenecen a mi zona horaria y le asignarán mi zona horaria. Lamentablemente, los datos que deseo importar no son de mi período de tiempo, así que esto no funciona.Cambiando el valor de la zona horaria de los datos

La base de datos también contiene datos con diferentes zonas horarias. Sin embargo, la zona horaria dentro de una tabla es siempre la misma.

Ahora, podría establecer el huso horario de la base de datos en la zona horaria de los datos que deseo importar antes de importar los datos (usando el comando SET time zone) y volver a cambiar a mi huso horario una vez que la importación finalice, y Estoy bastante seguro de que los datos almacenados no se verán afectados por el cambio de zona horaria de la base de datos. Pero este parece ser un enfoque bastante sucio y puede causar problemas más adelante.

Me pregunto si existe una forma más elegante de especificar la zona horaria para la importación sin tener los datos de zona horaria en los datos en sí.

Además, no he encontrado una manera de editar la información de zona horaria después de la importación. ¿Hay alguna manera de no convertir, sino simplemente editar la zona horaria para una tabla completa, suponiendo que toda la tabla tiene el mismo desplazamiento de zona horaria (es decir, si se ha asignado una incorrecta al ingresar/importar datos)?

Editar:
me las arreglé para especificar una zona horaria a la importación, todo el ser de comandos:

set session time zone 'UTC'; 
COPY tbl FROM 'c:\Users\Public\Downloads\test.csv' DELIMITERS ',' CSV; 
set session time zone 'CET'; 

Los datos luego se importadas utilizando la zona de tiempo de la sesión. Supongo que esto no tiene ningún efecto sobre otras consultas en la base de datos al mismo tiempo desde otras conexiones.

Edición 2:
he encontrado la manera de cambiar la zona horaria de una mesa después:
PostgreSQL update time zone offset

supongo que es más elegante para cambiar la zona horaria de la tabla después de la importación a continuación, utilizar la sesión para cambiar la zona horaria local temporal. Suponiendo que toda la mesa tiene el mismo huso horario, por supuesto.

Así que el código sería ahora algo a lo largo de la línea:

COPY tbl FROM 'c:\Users\Public\Downloads\test.csv' DELIMITERS ',' CSV; 
UPDATE tbl SET <tstz_field> = <tstz_field> AT TIME ZONE '<correct_time_zone>'; 
+0

¿Cómo estás realizando su importación? ¿No puedes asignar la zona horaria al importar? – ertx

+0

Gracias por la sugerencia, actualicé mi publicación, pero no estoy seguro de qué tipo de configuración de efectos tenga la zona horaria de la sesión en otros procesos dentro de la base de datos en el momento de la ejecución. – harbun

Respuesta

11

Es mucho más eficiente para establecer la zona horaria de su sesión de importación de actualizar los valores más tarde.

Me da la impresión de que usted piensa en la zona horaria como una configuración que se aplica a los valores que de otra manera no se modifican en las tablas. Pero no es así en absoluto. Piénselo como un modificador de entrada/salida. Los valores reales timestamp (con o sin zona horaria) son siempre almacenados como marcas de tiempo UTC internamente (número de segundos desde '2000-01-01 00:00').Mucho más detalles:

El UPDATE en su segundo ejemplo duplica el tamaño de la tabla, ya que cada hilera se invalida y una nueva versión añade (así es como UPDATE obras con MVCC en Postgres). Además de la costosa operación, VACUUM tendrá que hacer más trabajo más tarde para limpiar la hinchazón de la tabla. Muy ineficaz.

Es perfectamente seguro a SET la zona horaria local de la sesión. Esto no afecta las operaciones concurrentes de ninguna manera. Por cierto, SET SESSION es lo mismo que simple SET porque SESSION es el valor predeterminado de todos modos.

Si quieres ser absolutamente seguro, puede limitar el ajuste a la corriente transacción con SET LOCAL. Cito los manuales here

Los efectos de SET LOCAL duran sólo hasta el final de la transacción actual, ya sea cometido o no. Un caso especial es SET seguido por SET LOCAL en una sola transacción: el valor SET LOCAL será visto hasta el final de la transacción, pero después (si la transacción es comprometido) el valor SET tendrán efecto.

Armar:

BEGIN; 
SET LOCAL timezone = 'UTC'; 
COPY tabledata FROM 'c:\Users\Public\Downloads\test.csv' DELIMITERS ',' CSV; 
COMMIT; 

Comprobar:

SHOW timezone; 
+0

** Exactamente ** lo que necesitaba saber, gran explicación. Danke Erwin. :) – harbun

+0

@harbun: Bitteschön. :) –

Cuestiones relacionadas