Saltar al contenido principal

Tipos Postgres-Rust

Rust typePostgres type(s)
boolBOOL
i8“CHAR”
i16SMALLINT, SMALLSERIAL, INT2
i32INT, SERIAL, INT4
i64BIGINT, BIGSERIAL, INT8
f32REAL, FLOAT4
f64DOUBLE PRECISION, FLOAT8
&strStringVARCHAR, CHAR(N), TEXT, NAME, CITEXT
&[u8]Vec<u8>BYTEA
()VOID
PgMoneyMONEY

NUMERIC

  • Requiere la feature bigdecimal o rust_decimal y también el crate para el tipo elegido
  • NUMERIC no devuelve f32 o f64 sino que devuelve decimal
  • BigDecimal puede representar valores con un rango mucho mayor que el tipo NUMERIC en Postgres.
  • RustDecimal tiene un rango más pequeño que NUMERIC
  • NUMERIC puede representar todos los valores posibles de rust_decimal::Decimal, pero no al revés. Esto significa que la codificación nunca debería fallar, pero la decodificación sí
Rust typePostgres type(s)
bigdecimal::BigDecimalNUMERIC
rust_decimal::DecimalNUMERIC

Tiempo

Siempre que el dato represente un momento real en el tiempo (como created_at, updated_at, etc.) usar:

  • TIMESTAMPTZ en Postgres
  • chrono::DateTime<Utc> o time::OffsetDateTime en Rust
  • Cuando no se guarda con UTC o zona horaria, si se lee en otras regiones puede cambiar el significado

Usar tipos sin zona horaria (TIMESTAMP, PrimitiveDateTime, etc.) solo si:

  • La zona no importa (ej: horarios fijos)
  • No se está representando un instante real en el tiempo global

Time

  • Requiere la feature time y el crate time
Rust typePostgres type(s)DescripciónExample
time::PrimitiveDateTimeTIMESTAMPFecha y hora sin zona horaria2025-04-15 18:30:00
time::OffsetDateTimeTIMESTAMPTZFecha y hora con zona horaria (offset)2025-04-15 18:30:00+00
time::DateDATESolo la fecha2025-04-15
time::TimeTIMESolo la hora18:30:00
PgTimeTzTIMETZHora con zona horaria18:30:00-05

Chrono

  • Requiere la feature chrono y el crate chrono
Rust typePostgres type(s)DescripciónExample
chrono::DateTime<Utc>TIMESTAMPTZFecha y hora en UTC2025-04-15 18:30:00+00
chrono::DateTime<Local>TIMESTAMPTZFecha y hora en zona local2025-04-15 13:30:00-05
chrono::NaiveDateTimeTIMESTAMPFecha y hora sin zona horaria2025-04-15 18:30:00
chrono::NaiveDateDATESolo la fecha2025-04-15
chrono::NaiveTimeTIMESolo la hora18:30:00
PgTimeTzTIMETZHora con zona horaria18:30:00-05

Uuid

  • Requiere la feature uuid y el crate uuid
Rust typePostgres type(s)
uuid::UuidUUID

Json

  • Requiere la feature json
  • ValueRawValue de serde_json se pueden utilizar para datos JSON no estructurados con Postgres.
  • sqlx::types::Json<T> se puede utilizar para datos JSON estructurados con Postgres.
Rust typePostgres type(s)
sqlx::types::Json<T>JSON, JSONB
serde_json::ValueJSON, JSONB
&serde_json::value::RawValueJSON, JSONB

Vectores

Rust typePostgres type(s)
Vec<T> o &[T]ARRAY

Enums

Enum nativo de PostgreSQL Aquí el enum se mapea al tipo mood que se crea en PostgreSQL con CREATE TYPE mood AS ENUM (...). Los valores se almacenan como un enum real de PostgreSQL.

CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy');
#[derive(sqlx::Type)]
#[sqlx(type_name = "mood", rename_all = "lowercase")]
enum Mood { Sad, Ok, Happy }

Como entero Las enumeraciones de Rust también pueden definirse para representarse como un entero mediante repr. El siguiente tipo espera un tipo SQL INTEGERINT4 y se convertirá a/desde la enumeración de Rust.

#[derive(sqlx::Type)]
#[repr(i32)]
enum Mood {
Sad = 0,
Ok = 1,
Happy = 2
}

Como texto Los valores se almacenan como strings ("Sad", "Ok", "Happy") en una columna TEXT regular de PostgreSQL.

La ventaja de usar type_name = "text" es que no se necesita crear un tipo enum personalizado en PostgreSQL - se utiliza cualquier columna de tipo TEXT existente. SQLx automáticamente convierte entre los valores del enum de Rust y las strings en la base de datos.

Es útil cuando se trabaja con bases de datos existentes que ya tienen columnas de texto para representar estados o categorías, o cuando se requiere más flexibilidad sin definir tipos personalizados en PostgreSQL.

#[derive(sqlx::Type)]
#[sqlx(type_name = "text")]
enum Mood { Sad, Ok, Happy }

Ejemplo

Cargo.toml
# Base de datos (PostgreSQL)
sqlx = { version = "0.8.1", features = [
  "runtime-tokio",
  "tls-rustls-ring",
  "postgres",
  "uuid",
  "time",
  "rust_decimal",
] }

# Para algunos tipos de la base de datos
uuid = { version = "1.10.0", features = ["v4", "serde"] }
time = { version = "=0.3.36" }
rust_decimal = "1.36"