Comenzar
Solo necesitas un token de API de GribStream y un cliente o una biblioteca compatible con MySQL.
- Crea un token de API gratuito o usa uno que ya tengas.
- Usa
gribstreamcomo nombre de usuario y el token de API como contraseña. - Selecciona un dataset, por ejemplo
gfs, como base de datos y conéctate.
mysql --host=mysql.gribstream.com \
--port=3307 \
--user=gribstream \
--password \
--database=gfs \
--quick
El cliente de línea de comandos de MySQL solicita el token sin guardarlo en el historial del shell. En este comando, --quick hace que el cliente muestre las filas a medida que llegan, en lugar de esperar a tener el resultado completo. Otros clientes tienen opciones distintas para leer resultados de forma incremental.
Las consultas MySQL usan el mismo token y la misma cuota que las consultas de la API HTTP. El uso se calcula según los datos meteorológicos leídos para responder. Si no sabes qué dataset elegir, explora el catálogo de modelos; gfs es un buen punto de partida global.
¿Por qué MySQL?
Los lenguajes y las herramientas con un driver MySQL pueden usar una conexión conocida para consultar GribStream. No necesitas administrar un servidor MySQL, importar archivos meteorológicos ni aprender una biblioteca nueva.
La conexión es de solo lectura y está diseñada para datos meteorológicos. Los datasets aparecen como bases de datos, los campos meteorológicos se pueden explorar y el SQL no compatible devuelve un error claro.
Busca una columna meteorológica y consúltala
Cada parámetro meteorológico de GribStream aparece como una columna MySQL propia del dataset. Después de elegir un dataset, consulta sus columnas antes de escribir la consulta:
SHOW FULL COLUMNS FROM gfs.timeseries;
En el resultado, copia el valor de Field que necesites. Comment indica su nombre legible, las unidades nativas y el equivalente exacto con GS_VALUE(...). Para la temperatura GFS a 2 m, la columna es tmp_2_m_above_ground.
Estas tres formas identifican el mismo parámetro meteorológico. La columna es la forma SQL más sencilla; GS_VALUE es la alternativa de selector exacto para traducir una consulta existente de la API HTTP o elegir el selector dinámicamente. La forma JSON es la que aparece en las páginas de modelos.
tmp_2_m_above_ground
GS_VALUE
GS_VALUE(
'TMP',
'2 m above ground',
''
)
{
"name": "TMP",
"level": "2 m above ground",
"info": ""
}
Copia los nombres de las columnas meteorológicas desde SHOW FULL COLUMNS o gribstream.selector_columns en lugar de construirlos. La mayoría son legibles; los nombres largos o que colisionan reciben un sufijo determinista. Los selectores exactos distinguen mayúsculas y minúsculas.
Esta consulta devuelve las próximas seis horas de temperatura GFS a 2 m para un punto:
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN NOW() AND NOW() + INTERVAL 6 HOUR
AND lat = 40.758
AND lon = -73.985
AND lead_time BETWEEN '0h' AND '48h'
ORDER BY forecasted_time
LIMIT 100;
Esta columna meteorológica publica valores en kelvin. Consulta su Comment o el catálogo para conocer las unidades, en lugar de deducirlas del nombre de la columna o del alias.
El resultado contiene filas normales. Los siguientes valores son ilustrativos:
forecasted_time temp_k
2026-08-07 12:00:00 298.4
2026-08-07 13:00:00 299.1
2026-08-07 14:00:00 299.7
Usa el flujo de búsqueda en el catálogo para buscar columnas por nombre de parámetro, consultar sus unidades y recuperar el selector JSON exacto o la expresión GS_VALUE cuando los necesites.
Si la conexión ya ha seleccionado gfs, usa FROM timeseries. De lo contrario, indica la tabla como gfs.timeseries.
Parte de una consulta que funciona
Elige el ejemplo más parecido a tu objetivo, ábrelo y cambia solo el dataset, la columna meteorológica encontrada, los tiempos o los lugares que necesites. Copia los nombres desde SHOW FULL COLUMNS en lugar de intentar deducir cómo se normaliza un selector.
Consultar varios lugares con nombre en un rango de tiempo
SELECT forecasted_time, name, lat, lon,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T06:00:00Z'
AND (lat, lon, name) IN (
(40.758, -73.985, 'Times Square'),
(29.7604, -95.3698, 'Houston'),
(51.5072, -0.1276, 'London')
);
Consultar una grilla regular de latitud y longitud
Los valores más pequeños de grid_step seleccionan más puntos y consumen más cuota. Empieza con un paso amplio y reduce el área antes de aumentar la resolución.
SELECT forecasted_time, lat, lon,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T06:00:00Z'
AND lat BETWEEN 25 AND 50
AND lon BETWEEN -125 AND -66
AND grid_step = 1;
Consultar varios tiempos de pronóstico exactos y no contiguos
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time IN (
'2026-07-13T00:00:00Z',
'2026-07-13T06:00:00Z',
'2026-07-14T18:00:00Z'
)
AND lat = 40.758
AND lon = -73.985;
Consultar pronósticos de ejecuciones concretas del modelo
SELECT forecasted_at, forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM gfs.runs
WHERE forecasted_at BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T12:00:00Z'
AND lead_time BETWEEN '0h' AND '48h'
AND lat = 40.758
AND lon = -73.985
ORDER BY forecasted_at, forecasted_time;
Reproducir los pronósticos disponibles antes de un corte histórico
SELECT forecasted_at, forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-14T00:00:00Z'
AND forecasted_at <= '2026-07-12T18:00:00Z'
AND lat = 40.758
AND lon = -73.985
ORDER BY forecasted_time;
Consultar miembros concretos de un ensemble
SELECT forecasted_time, member,
tmp_2_m_above_ground AS temp_k
FROM gefsatmos.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T12:00:00Z'
AND member IN (0, 1, 2)
AND lead_time BETWEEN '0h' AND '48h'
AND lat = 40.758
AND lon = -73.985;
Convertir un valor y conservar solo las filas que cumplen un umbral
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k,
temp_k - 273.15 AS temp_c
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-14T00:00:00Z'
AND lat = 40.758
AND lon = -73.985
AND temp_c BETWEEN 18 AND 24;
Encontrar los puntos más cálidos de una grilla para un tiempo de pronóstico
SELECT forecasted_time, lat, lon,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time = '2026-07-13T18:00:00Z'
AND lat BETWEEN 25 AND 50
AND lon BETWEEN -125 AND -66
AND grid_step = 0.5
ORDER BY temp_k DESC
LIMIT 20;
Conéctate desde tu lenguaje de programación
Elige un lenguaje de programación. Cada ejemplo establece una conexión segura, ejecuta la misma consulta meteorológica pequeña y lee sus filas. Guarda el token en una variable de entorno o en un gestor de secretos; no lo incluyas en una cadena de conexión guardada en el código.
Cliente de línea de comandos de MySQL 8. TLS se negocia automáticamente; añade --quick para recibir el resultado de forma incremental.
mysql \
-h mysql.gribstream.com -P 3307 \
-u gribstream -p -D gfs \
--quick
Connector/Python mediante SQLAlchemy y pandas. Con chunksize, pandas devuelve un iterador de DataFrames en lugar de reunir el resultado completo.
import os
import certifi
import pandas as pd
from sqlalchemy import URL, create_engine
url = URL.create(
"mysql+mysqlconnector",
username="gribstream",
password=os.environ["GRIBSTREAM_API_TOKEN"],
host="mysql.gribstream.com",
port=3307,
database="gfs",
)
engine = create_engine(url, connect_args={
"ssl_verify_cert": True,
"ssl_verify_identity": True,
"ssl_ca": certifi.where(),
})
sql = """
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM timeseries
WHERE forecasted_time BETWEEN NOW() AND NOW() + INTERVAL 6 HOUR
AND lat = 40.758 AND lon = -73.985
ORDER BY forecasted_time
"""
for frame in pd.read_sql_query(sql, engine, chunksize=10_000):
print(frame.head())
Connector/J. Su modo de lectura progresiva utiliza Integer.MIN_VALUE como tamaño de lote.
String SQL = """
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM timeseries
WHERE forecasted_time BETWEEN NOW() AND NOW() + INTERVAL 6 HOUR
AND lat = 40.758 AND lon = -73.985
ORDER BY forecasted_time
""";
String url = "jdbc:mysql://mysql.gribstream.com:3307/gfs?sslMode=VERIFY_IDENTITY";
Properties props = new Properties();
props.setProperty("user", "gribstream");
props.setProperty("password", System.getenv("GRIBSTREAM_API_TOKEN"));
try (Connection db = DriverManager.getConnection(url, props);
Statement statement = db.createStatement(
ResultSet.TYPE_FORWARD_ONLY,
ResultSet.CONCUR_READ_ONLY)) {
statement.setFetchSize(Integer.MIN_VALUE);
try (ResultSet rows = statement.executeQuery(SQL)) {
while (rows.next()) {
System.out.println(rows.getTimestamp("forecasted_time"));
}
}
}
MySqlConnector para .NET. El lector consume las filas secuencialmente.
const string SQL = @"
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM timeseries
WHERE forecasted_time BETWEEN NOW() AND NOW() + INTERVAL 6 HOUR
AND lat = 40.758 AND lon = -73.985
ORDER BY forecasted_time";
var builder = new MySqlConnectionStringBuilder {
Server = "mysql.gribstream.com",
Port = 3307,
Database = "gfs",
UserID = "gribstream",
Password = Environment.GetEnvironmentVariable("GRIBSTREAM_API_TOKEN"),
SslMode = MySqlSslMode.VerifyFull,
};
await using var db = new MySqlConnection(builder.ConnectionString);
await db.OpenAsync();
await using var command = new MySqlCommand(SQL, db);
await using var rows = await command.ExecuteReaderAsync(
CommandBehavior.SequentialAccess);
while (await rows.ReadAsync()) {
Console.WriteLine(rows.GetDateTime("forecasted_time"));
}
go-sql-driver/mysql. Al iterar con Rows.Next, el resultado se consume sin construir un slice con todas las filas.
const query = `
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM timeseries
WHERE forecasted_time BETWEEN NOW() AND NOW() + INTERVAL 6 HOUR
AND lat = 40.758 AND lon = -73.985
ORDER BY forecasted_time`
cfg := mysql.NewConfig()
cfg.User = "gribstream"
cfg.Passwd = os.Getenv("GRIBSTREAM_API_TOKEN")
cfg.Net = "tcp"
cfg.Addr = "mysql.gribstream.com:3307"
cfg.DBName = "gfs"
cfg.TLSConfig = "true"
cfg.ParseTime = true
db, err := sql.Open("mysql", cfg.FormatDSN())
if err != nil { log.Fatal(err) }
defer db.Close()
rows, err := db.QueryContext(ctx, query)
if err != nil { log.Fatal(err) }
defer rows.Close()
for rows.Next() {
var validTime time.Time
var tempK float64
if err := rows.Scan(&validTime, &tempK); err != nil { log.Fatal(err) }
}
API de callbacks de mysql2. El stream de la consulta respeta el control de flujo de Node.
import mysql from 'mysql2';
const SQL = `
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM timeseries
WHERE forecasted_time BETWEEN NOW() AND NOW() + INTERVAL 6 HOUR
AND lat = 40.758 AND lon = -73.985
ORDER BY forecasted_time`;
const db = mysql.createConnection({
host: 'mysql.gribstream.com',
port: 3307,
user: 'gribstream',
password: process.env.GRIBSTREAM_API_TOKEN,
database: 'gfs',
ssl: {},
});
db.query(SQL)
.stream({ highWaterMark: 64 })
.on('data', row => console.log(row.forecasted_time))
.on('error', err => { throw err; })
.on('end', () => db.end());
Crate mysql de Rust. query_iter entrega las filas sin reunirlas en un Vec.
use mysql::{OptsBuilder, Pool, SslOpts};
use mysql::prelude::Queryable;
let sql = r#"
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM timeseries
WHERE forecasted_time BETWEEN NOW() AND NOW() + INTERVAL 6 HOUR
AND lat = 40.758 AND lon = -73.985
ORDER BY forecasted_time"#;
let opts = OptsBuilder::new()
.ip_or_hostname(Some("mysql.gribstream.com"))
.tcp_port(3307)
.user(Some("gribstream"))
.pass(std::env::var("GRIBSTREAM_API_TOKEN").ok())
.db_name(Some("gfs"))
.ssl_opts(Some(SslOpts::default()));
let pool = Pool::new(opts)?;
let mut db = pool.get_conn()?;
let rows = db.query_iter(sql)?;
for row in rows {
println!("{:?}", row?);
}
API C de MySQL. mysql_use_result lee una fila cada vez.
const char *sql =
"SELECT forecasted_time, "
"tmp_2_m_above_ground AS temp_k "
"FROM timeseries "
"WHERE forecasted_time BETWEEN NOW() AND NOW() + INTERVAL 6 HOUR "
"AND lat = 40.758 AND lon = -73.985 "
"ORDER BY forecasted_time";
MYSQL *db = mysql_init(NULL);
unsigned int ssl_mode = SSL_MODE_VERIFY_IDENTITY;
mysql_options(db, MYSQL_OPT_SSL_MODE, &ssl_mode);
mysql_real_connect(db, "mysql.gribstream.com", "gribstream",
getenv("GRIBSTREAM_API_TOKEN"), "gfs", 3307, NULL, 0);
mysql_query(db, sql);
MYSQL_RES *result = mysql_use_result(db);
MYSQL_ROW row;
while ((row = mysql_fetch_row(result)) != NULL) {
printf("%s\n", row[0]);
}
mysql_free_result(result);
mysql_close(db);
1. Adjunta GribStream
DuckDB puede adjuntar la conexión mediante su extensión MySQL y consultar las columnas meteorológicas como tablas remotas. Guarda las credenciales en las variables de entorno MYSQL_* habituales y adjunta la base de datos en modo de solo lectura.
export MYSQL_HOST=mysql.gribstream.com
export MYSQL_TCP_PORT=3307
export MYSQL_USER=gribstream
export MYSQL_PWD="$GRIBSTREAM_API_TOKEN"
export MYSQL_DATABASE=gfs
ATTACH 'ssl_mode=verify_identity' AS gribstream_db
(TYPE mysql, READ_ONLY);
2. Consulta un punto o una grilla regular
Las consultas normales sobre tablas adjuntas admiten por ahora un punto, como en el ejemplo, o una grilla regular definida mediante límites de latitud y longitud y grid_step. Mantén en la consulta de DuckDB las condiciones de tiempo, ubicación y lead time para que puedan enviarse a GribStream antes de devolver las filas.
SELECT forecasted_time, lead_time, lat, lon,
tmp_2_m_above_ground AS temp_k
FROM gribstream_db.gfs.timeseries
WHERE forecasted_time BETWEEN CURRENT_TIMESTAMP
AND CURRENT_TIMESTAMP + INTERVAL 6 HOUR
AND lat = 40.758
AND lon = -73.985
AND lead_time BETWEEN 0 AND 48
LIMIT 100;
3. Enumera ubicaciones con una consulta sin transformar
Para solicitar varias coordenadas separadas a la vez, pasa una sentencia SQL de GribStream compatible mediante la función de tabla mysql_query de DuckDB. La sentencia interna se ejecuta directamente en la conexión MySQL, por lo que puede usar la sintaxis de tuplas de coordenadas de GribStream.
SELECT *
FROM mysql_query('gribstream_db', $sql$
SELECT forecasted_time, name, lat, lon,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN NOW() AND NOW() + INTERVAL 6 HOUR
AND (lat, lon, name) IN (
(40.758, -73.985, 'Times Square'),
(29.7604, -95.3698, 'Houston')
)
AND lead_time BETWEEN '0h' AND '48h'
LIMIT 100
$sql$);
Para resultados grandes, usa el iterador de filas, el modo streaming o el equivalente de tu driver para evitar que reúna todo el resultado en memoria.
Elige timeseries o runs
Cada dataset expone las mismas dos formas de tabla meteorológica. Elige la tabla según la pregunta que quieras responder, no según las columnas que quieras devolver.
timeseries
Úsala para obtener el mejor pronóstico elegible en cada tiempo válido solicitado.
Filtra porforecasted_time
runs
Úsala para examinar los pronósticos de una o varias ejecuciones concretas del modelo.
Filtra porforecasted_atylead_time
forecasted_at es el tiempo de inicialización del modelo. forecasted_time es el tiempo válido que se pronostica. lead_time es la diferencia entre ambos en horas; se puede seleccionar o filtrar.
Ejemplo: consultar el historial de ejecuciones del modelo
SELECT forecasted_at, forecasted_time, lat, lon,
tmp_2_m_above_ground AS temp_k
FROM gfs.runs
WHERE forecasted_at BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T12:00:00Z'
AND lead_time BETWEEN '0h' AND '48h'
AND lat = 40.758
AND lon = -73.985
ORDER BY forecasted_at DESC, forecasted_time ASC;
Columnas disponibles, controles de consulta y metadatos de actualización
| Columna | Significado | Notas |
|---|---|---|
dataset | Código del dataset que produjo la fila | También es el nombre del esquema MySQL |
forecasted_at | Tiempo de inicialización del modelo | En timeseries, <= es el único operador admitido para cortar ejecuciones |
forecasted_time | Tiempo válido que se pronostica | La columna temporal principal de timeseries |
lat, lon, name | Punto resuelto y etiqueta opcional | name puede ser NULL |
member | Identificador del miembro del ensemble | Solo tiene significado en datasets de ensemble |
index_updated_at | Actualización más reciente de los datos de origen asociados a la fila | Metadato de actualización opcional, distinto de los dos tiempos del pronóstico |
lead_time, grid_step | Lead time del pronóstico en horas y separación de la grilla solicitada en grados | Se pueden seleccionar y filtrar; grid_step es NULL para puntos enumerados |
| Columnas meteorológicas propias del dataset | Valores meteorológicos nativos, como tmp_2_m_above_ground | Se descubren con SHOW FULL COLUMNS; los valores son DOUBLE |
Selecciona index_updated_at para ver la actualización más reciente de los datos de origen asociados a cada fila. Es un metadato de actualización, no el tiempo de inicialización del modelo; usa forecasted_at para identificar la ejecución.
SELECT forecasted_at, forecasted_time, index_updated_at,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T06:00:00Z'
AND lat = 40.758
AND lon = -73.985
ORDER BY forecasted_time;
Descubre datasets, columnas meteorológicas y selectores exactos
No adivines nombres de columnas, niveles de parámetros ni unidades. Busca un dataset, consulta sus columnas meteorológicas y recurre al mapeo del selector exacto solo cuando necesites la forma de la API o la alternativa GS_VALUE.
1. Busca un dataset
SELECT code, full_name, provider, min_lead_time, max_lead_time,
is_ensemble, member_count, members, parameter_count
FROM gribstream.datasets
WHERE code LIKE '%gfs%'
ORDER BY code;
Comprueba la cobertura del archivo y la cadencia antes de una consulta histórica grande
SELECT code, archive_start, archive_window, rolling_window,
time_resolution, run_cadence, min_lead_time, max_lead_time,
catalog_updated_at
FROM gribstream.datasets
WHERE code = 'gfs';
archive_start y archive_window describen la cobertura publicada; una ventana móvil puede avanzar. catalog_updated_at indica cuándo se actualizaron los metadatos del catálogo. Selecciona index_updated_at si necesitas conocer la actualización de cada fila.
2. Explora sus columnas meteorológicas
SHOW FULL COLUMNS FROM gfs.timeseries LIKE '%tmp%';
3. Busca el mapeo o usa un selector exacto
SELECT short_name, full_name, units, has_code_table, variation_count
FROM gribstream.parameters
WHERE dataset = 'gfs'
AND (short_name = 'TMP' OR full_name LIKE '%temperature%')
ORDER BY short_name
LIMIT 20;
SELECT column_name, full_name, units, name, level, info,
selector_json, gs_value_sql
FROM gribstream.selector_columns
WHERE dataset = 'gfs'
AND column_name = 'tmp_2_m_above_ground';
gribstream.selector_columns relaciona cada columna meteorológica con su nombre legible, unidades, selector JSON y expresión GS_VALUE equivalente. Requiere un filtro exacto por dataset.
Usa el column_name generado en las consultas SQL habituales. Usa GS_VALUE(name, level, info) cuando necesites una traducción directa de un selector de la API. Este selector de gefsatmosmean tiene un valor info no vacío, por lo que necesita los tres argumentos:
{
"name": "CAPE",
"level": "surface",
"info": "ens mean"
}
GS_VALUE(
'CAPE',
'surface',
'ens mean'
)
Las páginas de modelos siguen mostrando el selector JSON canónico y su alternativa exacta con GS_VALUE. Copia los nombres de columnas SQL desde el esquema en vivo, donde ya se han resuelto las colisiones y los identificadores largos.
4. Busca señales comparables entre datasets
Los parámetros compartidos enumeran conceptos meteorológicos comunes, unidades de salida y los datasets compatibles. Consulta este catálogo antes de comparar modelos y después resuelve la tupla exacta de cada dataset, sin suponer que los nombres de los selectores coinciden.
SELECT code, label, units, supported_datasets
FROM gribstream.shared_parameters
WHERE code = 'temperature_2m';
Ejemplo: calcular la velocidad del viento a 10 m
Después de encontrar los selectores exactos de las componentes del viento a 10 m de ifsoper, combínalos con func.Hypot:
SELECT forecasted_time,
v_10u_sfc AS u_component,
v_10v_sfc AS v_component,
func.Hypot(u_component, v_component) AS wind_speed
FROM ifsoper.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T06:00:00Z'
AND lat = 48.8566
AND lon = 2.3522
ORDER BY forecasted_time;
Sintaxis legible por máquinas y comandos de exploración MySQL
Úsalos cuando quieras que la propia conexión describa la sintaxis SQL y sus ejemplos:
SELECT topic, supported_syntax, example, notes
FROM gribstream.sql_dialect
ORDER BY topic;
SELECT name, description, `sql`
FROM gribstream.query_examples
ORDER BY name;
También están disponibles comandos MySQL habituales como SHOW TABLES, SHOW COLUMNS, DESCRIBE y SHOW CREATE TABLE. SHOW FULL COLUMNS incluye descripciones meteorológicas concisas y el mapeo exacto a GS_VALUE:
SHOW FULL COLUMNS FROM gfs.timeseries;
Tablas del catálogo
gribstream.datasetsgribstream.parametersgribstream.parameter_variationsgribstream.selector_columnsgribstream.shared_parametersgribstream.sql_dialectandgribstream.query_examples
Las consultas de metadatos admiten proyecciones o *, DISTINCT, ORDER BY, LIMIT con un desplazamiento no negativo y combinaciones acotadas de =, !=, LIKE, IN y comprobaciones de NULL.
Valores, cálculos y filtros
Las columnas calculadas usan expresiones SQL conocidas y pueden hacer referencia a alias definidos antes en la lista de selección. Primero asigna un alias a una columna meteorológica y luego reutilízalo. Escribe las conversiones de unidades de forma explícita:
SELECT forecasted_time,
tmp_2_m_above_ground AS temp_k,
temp_k - 273.15 AS temp_c
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T12:00:00Z'
AND lat = 40.758
AND lon = -73.985
AND (temp_c BETWEEN 18 AND 30 OR temp_c IS NULL);
Las condiciones sobre valores meteorológicos admiten BETWEEN, IN numérico, comprobaciones de NULL, paréntesis, NOT y combinaciones booleanas. Une con AND las condiciones de tiempo, ubicación, lead time, miembro y ejecución del modelo; usa OR solo dentro de condiciones sobre valores meteorológicos.
Funciones y cálculos más complejos
Las funciones numéricas habituales incluyen ABS, CEIL/CEILING, FLOOR, ROUND, SQRT, POW/POWER, MOD y TRUNCATE. Las etiquetas de los puntos admiten LOWER/LCASE, UPPER/UCASE, TRIM y CHAR_LENGTH, que cuenta caracteres Unicode. No se admite LENGTH, que en MySQL cuenta bytes; usa CHAR_LENGTH para los nombres.
SELECT forecasted_time,
ugrd_10_m_above_ground AS u,
vgrd_10_m_above_ground AS v,
func.Hypot(u, v) AS wind_speed
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T12:00:00Z'
AND lat = 40.758
AND lon = -73.985
AND wind_speed > 5;
Las funciones de expresión adicionales de GribStream usan el espacio de nombres explícito func.. Las expresiones admiten literales, paréntesis, operadores unarios, aritmética, comparaciones y combinaciones booleanas. Consulta la referencia de expresiones para ver las llamadas func. registradas y sus argumentos.
Unidades, tipos de datos y valores ausentes
Las columnas de parámetros meteorológicos y GS_VALUE devuelven las unidades nativas publicadas en el catálogo; un alias no convierte el valor. Comprueba has_code_table en gribstream.parameters antes de interpretar un campo codificado como una medida continua.
Los valores meteorológicos, las expresiones calculadas, la latitud y la longitud se devuelven como DOUBLE de MySQL. Las columnas temporales son DATETIME(6); los identificadores del dataset, del punto y del miembro son cadenas de texto. Los valores numéricos o temporales ausentes se convierten en NULL de SQL. Compruébalos con IS NULL o IS NOT NULL; = NULL no está admitido.
Sentencias preparadas
Los marcadores de posición normales de MySQL funcionan en selectores, cálculos, timestamps, coordenadas, miembros y filtros meteorológicos. Las funciones de tiempo relativo se evalúan al ejecutar la sentencia preparada, no al prepararla.
SELECT forecasted_time AS valid_time,
GS_VALUE(?, ?) AS temp_k,
temp_k - ? AS temp_c
FROM gfs.timeseries
WHERE forecasted_time BETWEEN ? AND ?
AND lat = ?
AND lon = ?
AND temp_c BETWEEN ? AND ?
LIMIT 100;
Resultados DISTINCT acotados
Las consultas meteorológicas pueden usar SELECT DISTINCT ... LIMIT n. La unicidad se aplica a la fila seleccionada completa. No se puede combinar con ORDER BY y la consulta puede tener que leer toda la selección acotada antes de saber que no quedan filas únicas. Úsalo para eliminar duplicados en un conjunto acotado, no como sustituto de limitar el tiempo y la ubicación.
SELECT DISTINCT name,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T06:00:00Z'
AND (lat, lon, name) IN (
(40.758, -73.985, 'Times Square'),
(29.7604, -95.3698, 'Houston')
)
LIMIT 100;
Rangos, tiempos relativos y zonas horarias
timeseries.forecasted_time es el tiempo válido. runs.forecasted_at es el tiempo de inicialización del modelo. Los rangos necesitan ambos límites e incluyen los dos extremos cuando se escriben con BETWEEN.
Para ventanas contiguas, utiliza un rango semiabierto como forecasted_time >= start AND forecasted_time < end. Así evitas devolver dos veces el instante del límite al combinar consultas consecutivas.
SELECT forecasted_at, forecasted_time,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN NOW() - INTERVAL 2 DAY AND NOW()
AND forecasted_at <= NOW() - INTERVAL 6 HOUR
AND lat = 40.758
AND lon = -73.985
LIMIT 100;
Funciones de tiempo relativo y formatos de timestamp admitidos
NOW(), CURRENT_TIMESTAMP y UTC_TIMESTAMP() se evalúan una vez por sentencia en UTC; se admite precisión fraccionaria como NOW(6). DATE_ADD, ADDDATE, DATE_SUB, SUBDATE y las formas + INTERVAL/- INTERVAL admiten unidades enteras fijas desde microsegundos hasta semanas. Se excluyen meses y años porque su duración varía.
Los literales temporales aceptan una fecha, una fecha y hora de MySQL, el formato ISO con T o RFC 3339 con desfase horario. Un literal sin desfase se interpreta como UTC, salvo cuando es la hora local de entrada de CONVERT_TZ.
Seleccionar tiempos exactos y no contiguos
Usa = para un tiempo exacto e IN para varios tiempos no contiguos. Usa forecasted_time con timeseries y forecasted_at con runs. Los ejemplos de consultas incluyen un caso completo.
Consultar un día local y gestionar el horario de verano
SELECT forecasted_time,
CONVERT_TZ(forecasted_time, 'UTC', 'Europe/Paris') AS paris_time,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time >=
CONVERT_TZ('2026-10-25 00:00:00', 'Europe/Paris', 'UTC')
AND forecasted_time <
CONVERT_TZ('2026-10-26 00:00:00', 'Europe/Paris', 'UTC')
AND lat = 48.8566
AND lon = 2.3522
LIMIT 100;
Las zonas IANA con nombre tienen en cuenta los cambios de horario de verano. El rango de París anterior abarca el día de 25 horas del 25 de octubre de 2026; el mismo patrón semiabierto también abarca correctamente el día de 23 horas del 29 de marzo. Los tiempos locales de entrada se convierten inmediatamente a UTC; los tiempos ambiguos o inexistentes producen un error claro. La conversión del resultado también acepta forecasted_at e index_updated_at. Conserva la columna UTC original cuando una hora local pueda aparecer dos veces. Los alias temporales proyectados son solo de presentación y no se pueden usar en WHERE.
Las conexiones permanecen en UTC. SET time_zone acepta valores equivalentes a UTC, SYSTEM o DEFAULT; usa CONVERT_TZ cuando necesites timestamps locales.
Aplicar un corte histórico por ejecución del modelo
En timeseries, forecasted_at <= timestamp excluye las ejecuciones posteriores. Es el único operador admitido para esa columna en timeseries; usa index_updated_at cuando la pregunta sea sobre la actualización de los datos. Los ejemplos de consultas incluyen un corte histórico completo.
Puntos, grillas, lead times y ensembles
Usa un par de coordenadas para un punto, una lista de tuplas para varios puntos con nombre o límites de latitud y longitud con grid_step para una grilla regular. Los ejemplos de consultas incluyen cada una de estas formas.
- Un punto: usa
lat = value AND lon = value. - Varios puntos: usa
(lat, lon)o(lat, lon, name)conIN. - Una grilla: limita ambas coordenadas y define
grid_stepen grados. Los pasos más pequeños seleccionan más puntos y consumen más cuota.
Filtros de lead time
Usa duraciones entre comillas, como lead_time = '24h'. BETWEEN selecciona un rango cerrado; las comparaciones emparejadas >=/< expresan un rango semiabierto; una comparación individual solo fija un mínimo o un máximo. Las duraciones admiten formas como '90m', '24h' o '168h'.
Filtros por miembro del ensemble
Comprueba is_ensemble y el array JSON members de gribstream.datasets antes de seleccionar miembros; no supongas que todos los datasets son ensembles ni que sus identificadores tienen el mismo rango. Los ejemplos de consultas incluyen una selección de miembros.
Mantén las consultas eficientes
El uso de cuota depende de los datos meteorológicos leídos para evaluar una consulta, no del número de filas devueltas. Una condición sobre un valor meteorológico o un alias calculado —por ejemplo, temp_c > 30— solo puede eliminar filas después de leer esos valores. Por tanto, una consulta grande puede consumir mucha cuota aunque sus filtros devuelvan muy pocas filas.
Las condiciones sobre el tiempo de pronóstico, la ubicación, el lead time y el miembro del ensemble reducen los datos seleccionados. Estas decisiones tienen el mayor efecto:
- Usa
timeseriessalvo que necesites el historial de varias ejecuciones del modelo. - Mantén cortos los rangos de tiempo o usa una lista de tiempos exactos.
- Selecciona solo las columnas de parámetros meteorológicos necesarias.
- Prefiere puntos exactos a una grilla extensa; si usas una grilla, elige un
grid_stepadecuado. - Limita
lead_timey selecciona solo los miembros necesarios del ensemble.
Usa el ordenamiento para explorar
ORDER BY está pensado principalmente para sesiones interactivas y exploración, cuando merece la pena recibir un resultado legible de inmediato. En una consulta acotada, ordenar primero por la columna temporal principal normalmente permite recibir filas de forma incremental. Usa forecasted_time con timeseries o forecasted_at con runs, elige cualquier dirección y añade columnas o alias seleccionados como claves secundarias cuando haga falta.
SELECT forecasted_time AS valid_time, name, lat, lon,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T12:00:00Z'
AND (lat, lon, name) IN (
(40.758, -73.985, 'Times Square'),
(29.7604, -95.3698, 'Houston'),
(51.5072, -0.1276, 'London')
)
ORDER BY valid_time DESC, temp_k DESC, name ASC;
Para runs, empieza por forecasted_at y limita los dos extremos de lead_time. Si un resultado ordenado es demasiado grande para procesarlo con seguridad, reduce la selección o elimina ORDER BY y ordena en tu aplicación.
En cargas históricas y otras descargas de gran volumen, omite ORDER BY. Si el orden importa, ordena los datos después de recibirlos. Así el ordenamiento no limita el rendimiento, sobre todo al combinar una selección amplia con filtros de valores meteorológicos.
Rankings globales
Un orden que comienza por un valor meteorológico debe examinar toda la selección antes de devolver filas, por lo que requiere LIMIT. Usa esta forma para rankings, no para recibir datos de forma incremental. Los ejemplos de consultas incluyen una consulta completa de puntos más cálidos.
Usa LIMIT para el tamaño del resultado, no para la cuota
LIMIT sirve para mantener pequeño el resultado interactivo, pero no determina cuántos datos meteorológicos se leen. Los filtros y el ordenamiento pueden leer muchos más datos de los que contiene el resultado final. Usa los controles de selección anteriores para reducir el consumo de cuota.
Avanzado: valida una consulta con EXPLAIN
La mayoría de las consultas no necesitan EXPLAIN. Añádelo delante de una consulta meteorológica para validar la sentencia y ver información de diagnóstico sin recuperar filas ni consumir cuota. Resulta útil sobre todo para investigar problemas y solicitar soporte.
EXPLAIN
SELECT forecasted_time, lat, lon,
tmp_2_m_above_ground AS temp_k
FROM gfs.timeseries
WHERE forecasted_time BETWEEN '2026-07-13T00:00:00Z'
AND '2026-07-13T12:00:00Z'
AND (lat, lon) = (40.758, -73.985)
LIMIT 100;
Resultados incrementales, cancelación y errores
Las filas se vuelven disponibles de forma incremental. Que las veas de inmediato depende del cliente o la biblioteca MySQL, así que usa su interfaz sin búfer, de transmisión continua, iterativa o por bloques para consultas grandes. La opción exacta depende del cliente; el apéndice de clientes enlaza su documentación.
- Desconexión del cliente: cerrar la conexión cancela su consulta activa.
- Cliente MySQL: pulsa Ctrl+C para detener la consulta activa.
Cancelación desde aplicaciones y consultas simultáneas
Una conexión MySQL tiene una sola sentencia activa. Consume o cierra el resultado antes de reutilizarla; usa un pool de conexiones si la aplicación realmente necesita consultas simultáneas. Cada conexión del pool se autentica de forma independiente.
Usa la API de cancelación o el contexto cancelable de tu driver; el nombre y el comportamiento dependen del cliente. Para cancelar de forma explícita, ejecuta KILL QUERY <connection_id> desde otra conexión que use el mismo token de API. La conexión de destino se puede reutilizar.
Códigos de error MySQL
Los errores usan respuestas MySQL normales para que los clientes existentes los muestren de forma natural:
| Situación | Código MySQL | Mensaje |
|---|---|---|
| Sintaxis SQL | 1064 | Error de análisis o validación cerca de la entrada no admitida. |
| SQL no compatible | 1235 | Explicación concreta de la construcción no compatible. |
| Token no válido | 1045 | Acceso denegado al autenticar la conexión. |
| Consulta cancelada | 1317 | Se interrumpió la ejecución de la consulta. |
| Límite de uso | 1226 | El mensaje indica cuánto esperar antes de reintentar, cuando esa información está disponible. |
Solución de problemas
Reducir el ancho de banda de un resultado grande
Para descargas grandes, activa la compresión del protocolo MySQL si tu cliente o driver la admite. La opción depende del cliente; consulta la documentación oficial del apéndice.
Cliente MySQL: añade --compression-algorithms=zstd al conectarte.
Desde cualquier cliente puedes comprobar la compresión negociada con:
SHOW SESSION STATUS LIKE 'Compression%';
La conexión TLS no puede verificar el certificado o el nombre del host
Conéctate a mysql.gribstream.com, no a su dirección IP, y usa un almacén de certificados de confianza actualizado. Mantén activa la verificación de identidad; desactivarla puede ocultar un nombre de host incorrecto, una interceptación o certificados de confianza incompletos. La configuración depende del cliente; consulta el apéndice de clientes.
La conexión supera el tiempo de espera
Confirma que tu red permite conexiones TCP salientes a mysql.gribstream.com por el puerto 3307. Los firewalls corporativos y algunos notebooks restringidos bloquean puertos de base de datos no estándar.
No se reconoce una columna meteorológica o se rechaza un selector exacto
Ejecuta SHOW FULL COLUMNS FROM <dataset>.timeseries y copia el valor de Field en lugar de adivinarlo. Para usar un selector exacto en SQL, copia gs_value_sql desde gribstream.selector_columns; los selectores distinguen mayúsculas y minúsculas y no deben traducirse ni normalizarse.
Un valor tiene una escala, unidad o significado inesperado
GribStream devuelve los valores nativos publicados para el selector. Revisa units, description y has_code_table en el catálogo, y confirma level e info. Las conversiones de unidades son columnas calculadas explícitas; un alias AS nunca cambia los datos por sí solo.
Se rechaza un rango temporal, una zona horaria o una consulta ordenada
Indica los dos límites temporales. Convierte los límites expresados como hora local a UTC con CONVERT_TZ; no adivines una hora ambigua o inexistente por el cambio de horario. Si el orden solicitado no es seguro, reduce la selección o elimina ORDER BY y ordena en la aplicación.
No aparecen filas hasta que termina la consulta
El cliente está acumulando el resultado. Selecciona su modo no almacenado, streaming, iterativo o por bloques. Cliente MySQL: vuelve a conectarte con --quick. pandas: pasa chunksize. Para otros clientes, sigue la documentación de lectura de resultados del apéndice.
La consulta recibe el error MySQL 1226
Reduce la concurrencia o espera el tiempo indicado en el mensaje antes de reintentar. Reintentar de inmediato solo prolonga el límite.
Usar la conexión como herramienta autodescriptiva para agentes de IA
Cualquier conector genérico de base de datos MySQL —incluidos los expuestos como herramientas MCP— puede conectarse a mysql.gribstream.com:3307. Proporciona el token de API mediante la configuración secreta del conector.
Proporciona al agente el siguiente archivo de instrucciones (skill). El esquema y las tablas del catálogo le permiten descubrir datasets, columnas meteorológicas, unidades, mapeos de selectores exactos, reglas del dialecto y ejemplos listos para ejecutar antes de construir una consulta.
- Leer
gribstream.sql_dialectygribstream.query_examples. - Buscar en
gribstream.datasetsy después consultarSHOW FULL COLUMNSpara la tabla meteorológica elegida. - Usar
gribstream.selector_columnscuando se necesite el mapeo a un selector JSON exacto o aGS_VALUE. - Construir y ejecutar la consulta acotada más pequeña que responda a la pregunta.
- Usar
EXPLAINsolo para validar o investigar una consulta.
Descarga las instrucciones de GribStream MySQL para agentes, con el flujo completo, los límites de sintaxis y las reglas para recuperar datos.
SQL compatible y límites deliberados
Consultas meteorológicas
SELECTdesdetimeseriesyruns- Columnas meteorológicas descubiertas y alternativas exactas con
GS_VALUE - Alias calculados, funciones numéricas y de texto habituales, y llamadas
func.documentadas - Rangos y listas de tiempo, puntos, grillas, miembros y lead times
- Filtros booleanos sobre valores meteorológicos
- Ordenamiento que empieza por tiempo o top-N global acotado
DISTINCTacotado, sentencias preparadas y diagnóstico opcional conEXPLAIN
No compatible de forma intencional
- Escrituras, DDL, transacciones y bloqueos
- Joins, subconsultas, agregación y agrupación
SELECT *para resultados meteorológicos- Ordenamiento global sin límites y expresiones de orden
- Desplazamientos distintos de cero en resultados meteorológicos
- Funciones MySQL no enumeradas y conversiones SQL implícitas
Estos límites mantienen las consultas previsibles, permiten entregar resultados de forma incremental y producen errores claros, en lugar de aceptar SQL con resultados sorprendentes.
Matriz de compatibilidad completa
| Área | Formas compatibles | Límite |
|---|---|---|
| Sesión | USE, VERSION(), DATABASE(), funciones temporales UTC, variables de sesión habituales y consultas de estado | Comportamiento de compatibilidad, no el conjunto completo de variables de un servidor MySQL |
| Exploración | SHOW DATABASES, SHOW TABLES, SHOW FULL COLUMNS, DESCRIBE, SHOW CREATE TABLE | Solo esquemas y tablas de GribStream |
SELECT de metadatos | Proyecciones o *, DISTINCT, filtros booleanos, ORDER BY, LIMIT y desplazamientos no negativos | Solo tablas del catálogo y de information_schema |
SELECT meteorológico | Columnas fijas y meteorológicas explícitas, alternativa GS_VALUE, cálculos, condiciones acotadas, filtros y DISTINCT limitado | Sin * meteorológico, joins, subconsultas, agrupación ni agregación |
| Ordenamiento | Hasta ocho claves seleccionadas; ordenamiento que empieza por tiempo o top-N global limitado | Sin expresiones, posiciones ordinales, claves repetidas ni ordenamiento global sin límites |
| Sentencias preparadas | Placeholders ? normales en selectores, expresiones, tiempos, ubicaciones, miembros y filtros | Hasta cinco sentencias preparadas por conexión |
| Diagnóstico avanzado | EXPLAIN SELECT ... | Valida sin ejecutar; EXPLAIN ANALYZE no está admitido |
| Cancelación | KILL QUERY connection_id desde una conexión que use el mismo token | No permite examinar ni cancelar el trabajo de otro token |
Apéndice: referencias de configuración por cliente
TLS, la compresión, la acumulación de resultados, la cancelación, los tiempos de espera y el pool de conexiones se configuran en el cliente o driver, no mediante SQL. Consulta la documentación de la biblioteca que utilices.
| Cliente | Documentación oficial | Sirve para |
|---|---|---|
| MySQL CLI | Opciones del cliente y opciones de conexión | TLS, compresión, --quick, tiempos de espera y otras opciones del cliente |
| Python | Argumentos de conexión de Connector/Python y read_sql de pandas | TLS, compresión, pool, opciones de conexión y DataFrames por bloques |
| Java | Propiedades de configuración de Connector/J | TLS, compresión, tiempos de espera y comportamiento de JDBC |
| C# / .NET | Opciones de conexión de MySqlConnector | TLS, compresión, pool y tiempos de espera |
| Go | Documentación de go-sql-driver/mysql | Opciones de DSN, TLS, compresión, tiempos de espera y pool |
| Node.js | Documentación de mysql2 | Conexiones, TLS, pools, sentencias preparadas y streaming de resultados |
| Rust | Documentación del crate mysql | TLS, compresión, pools e iteración de filas |
| C | Guía de la API C de MySQL | API de conexión y resultados |
| DuckDB | Extensión MySQL de DuckDB | Credenciales en variables de entorno, ATTACH de solo lectura, TLS, consultas de tablas remotas y mysql_query |
| DBeaver | Configuración de la conexión MySQL y configuración SSL | Conexión MySQL 8, SSL, confianza de certificados y navegación por la base de datos |
