Snippets Collections
%%configure -f
{
    "conf": {
        "spark.jars": "s3://memob-scripts/allpings/references/postgresql-42.7.7.jar"
    }
}

¡Excelente pregunta! Es fundamental entender cómo funciona el "mago detrás de la cortina". Te lo explico paso a paso:

El Flujo Completo del Formulario
1. Vista (Formulario) → Controlador
php
<?php
// Esto genera un formulario HTML que apunta al controlador actual
$form = ActiveForm::begin([
    'action' => ['libro/crear'], // ← ¡AQUÍ ESTÁ LA CLAVE!
    'method' => 'post'
]); 
?>
Esto genera HTML como:

html
<form action="/index.php?r=libro/crear" method="post">
    <input type="text" name="Libro[titulo]" value="">
    <input type="text" name="Libro[autor_id]" value="">
    <!-- ... otros campos -->
</form>
2. Controlador - Donde la Magia Ocurre
php
public function actionCrear()
{
    $model = new Libro();

    // ¡ESTA LÍNEA ES LA CLAVE!
    if ($model->load(Yii::$app->request->post()) && $model->validate()) {
        
        // Aquí se guarda en la base de datos
        if ($model->save()) {
            Yii::$app->session->setFlash('success', '¡Libro guardado!');
            return $this->redirect(['crear']);
        }
    }

    return $this->render('crear', ['model' => $model]);
}
Desglosemos el Proceso Mágico:
Paso 1: $model->load() - Recoge los Datos
php
// Esto hace automáticamente:
$postData = Yii::$app->request->post();
// $postData contiene: ['Libro' => ['titulo' => 'Mi libro', 'autor_id' => 1, ...]]

$model->titulo = $postData['Libro']['titulo'];
$model->autor_id = $postData['Libro']['autor_id'];
// ... y así con todos los campos
Paso 2: $model->validate() - Valida los Datos
php
// Usa las reglas que definiste en el modelo
public function rules()
{
    return [
        [['titulo', 'autor_id'], 'required'], // ← Se validan aquí
        [['titulo'], 'string', 'max' => 255],
    ];
}
Paso 3: $model->save() - Guarda en la BD
php
// Internamente hace:
public function save()
{
    if ($this->validate()) {
        // Genera y ejecuta el INSERT SQL automáticamente
        // INSERT INTO libros (titulo, autor_id, ...) VALUES ('Mi libro', 1, ...)
        return $this->insert(false);
    }
    return false;
}
Versión Visual del Flujo:
text
FORMULARIO HTML
     ↓ (envía POST)
CONTROLADOR actionCrear()
     ↓
$model->load()       ← Recoge datos del formulario
     ↓
$model->validate()   ← Verifica reglas
     ↓
$model->save()       ← INSERT en la base de datos
     ↓
REDIRIGE o MUESTRA ERROR
Ejemplo Práctico para Entender Mejor:
Tu Formulario Genera Esto:
html
<input type="text" name="Libro[titulo]" value="Cien años de soledad">
<input type="number" name="Libro[autor_id]" value="1">
El Controlador Recibe Esto:
php
// Yii::$app->request->post() contiene:
[
    'Libro' => [
        'titulo' => 'Cien años de soledad',
        'autor_id' => '1',
        'categoria_id' => '2',
        // ...
    ]
]
Y $model->load() Transforma Esto:
php
// Convierte automáticamente:
$model->titulo = 'Cien años de soledad';
$model->autor_id = 1;
$model->categoria_id = 2;
// ...
¿Cómo Sabe Dónde Guardar?
El Modelo Sabe Su Tabla:

php
class Libro extends ActiveRecord
{
    public static function tableName()
    {
        return 'libros'; // ← ¡Sabe que guarda en la tabla 'libros'!
    }
}
ActiveRecord Genera el SQL:

php
// Automáticamente crea:
INSERT INTO libros (titulo, autor_id, categoria_id, ...) 
VALUES ('Cien años de soledad', 1, 2, ...)
En Resumen:
El formulario envía datos al controlador via POST

$model->load() mapea los datos del formulario al modelo

$model->validate() verifica que todo esté correcto

$model->save() genera y ejecuta el INSERT automáticamente

La magia está en que Yii2 hace todo el trabajo pesado por ti: no necesitas escribir SQL, no necesitas mapear campos manualmente, todo es automático y seguro.

¿Quieres que profundice en alguna parte específica?

Guía Detallada para Avanzar en PostgreSQL
Vamos a explorar cada punto con explicaciones claras y muchos ejemplos prácticos para que aprendas PostgreSQL a fondo.

1. Configuración avanzada del servidor y optimización
PostgreSQL usa un archivo llamado postgresql.conf para ajustar su comportamiento.

listen_addresses: en qué interfaces de red escucha; por defecto es todas ('*').

port: puerto estándar es 5432.

max_connections: máximo de conexiones concurrentes; por ejemplo, 100.

shared_buffers: memoria usada para caching, se recomienda ~25% de RAM.

work_mem: memoria para operaciones de ordenamiento y joins; un valor típico es 8MB.

maintenance_work_mem: para mantenimiento como VACUUM.

effective_cache_size: estima la caché del sistema operativo para planificación de consultas.

Ejemplo básico de configuración:
text
listen_addresses = '*'
port = 5432
max_connections = 100
shared_buffers = 1024MB
work_mem = 8MB
maintenance_work_mem = 256MB
effective_cache_size = 2048MB
Para aplicar cambios: generalmente con SELECT pg_reload_conf(); o reiniciar el servidor.

2. Tipos de datos complejos y funciones avanzadas
PostgreSQL soporta tipos avanzados:

ARRAY: almacenar listas en una columna.

JSON / JSONB: datos estructurados para aplicaciones web.

hstore: pares clave-valor.

UUID: identificadores únicos.

Tipos geométricos, rango, XML, y más.

Ejemplo con JSONB:
sql
CREATE TABLE productos (
  id SERIAL PRIMARY KEY,
  info JSONB
);

INSERT INTO productos (info) VALUES ('{"nombre": "Manzana", "precio": 1.25}');

-- Consultar precio
SELECT info->>'precio' AS precio FROM productos;
Funciones avanzadas incluyen agregados personalizados, funciones de ventana, expresiones regulares, y SQL/PL.

3. Índices, vistas, secuencias y otros objetos
Índices aceleran búsquedas:

sql
CREATE INDEX idx_nombre ON empleados(nombre);
Vistas Son consultas guardadas:

sql
CREATE VIEW vista_ventas AS
SELECT cliente, SUM(total) AS total_ventas FROM ventas GROUP BY cliente;
Secuencias para números automáticos:

sql
CREATE SEQUENCE seq_pedido START 1;
SELECT nextval('seq_pedido');
Otros objetos: funciones, triggers, esquemas.

4. Consultas complejas y optimización
Uso de JOINs para unir tablas:

sql
SELECT e.nombre, d.nombre AS departamento
FROM empleados e
JOIN departamentos d ON e.departamento_id = d.id;
Subconsultas:

sql
SELECT nombre FROM empleados WHERE salario > (SELECT AVG(salario) FROM empleados);
Funciones de ventana:

sql
SELECT nombre, salario, RANK() OVER (ORDER BY salario DESC) FROM empleados;
Optimización:

Usa EXPLAIN para ver el plan de ejecución.

Crea índices apropiados.

Evita SELECT * si no necesitas todas las columnas.

Usa LIMIT y OFFSET para paginación.

5. Seguridad, roles y autenticación
Crear roles:

sql
CREATE ROLE lector LOGIN PASSWORD 'pass123';
GRANT SELECT ON empleados TO lector;
Revocar permisos:

sql
REVOKE SELECT ON empleados FROM lector;
Configuración en pg_hba.conf controla qué hosts y con qué métodos pueden conectar.

6. Replicación, backups y recuperación
Replicación: permite tener copias de la base para alta disponibilidad.

Configurar wal_level, max_wal_senders, hot_standby.

Replica física o lógica.

Backups:

pg_dump para backups lógicos.

pg_basebackup para copias físicas.

Recuperación:

Restaurar con pg_restore o psql.

Point-In-Time Recovery configurando WAL.

7. PL/pgSQL: procedimientos almacenados y triggers
Crear función:

sql
CREATE FUNCTION suma(a INT, b INT) RETURNS INT AS $$
BEGIN
  RETURN a + b;
END;
$$ LANGUAGE plpgsql;
Crear trigger para log de inserciones:

sql
CREATE TABLE log_inserciones (id SERIAL, tabla TEXT, fecha TIMESTAMP);

CREATE FUNCTION log_insert() RETURNS trigger AS $$
BEGIN
  INSERT INTO log_inserciones(tabla, fecha) VALUES (TG_TABLE_NAME, now());
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

CREATE TRIGGER trig_insert
  AFTER INSERT ON empleados
  FOR EACH ROW EXECUTE FUNCTION log_insert();
8. Integración y gestión de rendimiento
Pools de conexiones con PgBouncer para manejar muchas conexiones.

Monitoreo con herramientas como pg_stat_activity, pg_stat_statements.

Profiling y optimización con EXPLAIN ANALYZE.

Integración en aplicaciones con drivers (psycopg2 para Python, pg JDBC, etc).

Ajuste de parámetros según uso para mejorar rendimiento.

Conclusión
Esta guía te da los fundamentos y ejemplos necesarios para avanzar hacia un dominio completo de PostgreSQL. Para cada punto, te recomiendo practicar en un entorno real y usar documentación oficial para profundizar según tus necesidades.
DO $$
BEGIN
   IF NOT EXISTS (
      SELECT 1 
      FROM pg_class c
      JOIN pg_namespace n ON n.oid = c.relnamespace
      WHERE c.relname = 'carrier_id_seq'
        AND n.nspname = 'lookup'
   ) THEN
      CREATE SEQUENCE lookup.carrier_id_seq OWNED BY lookup.carrier.id;
   END IF;
END$$;

-- Make id use sequence
ALTER TABLE lookup.carrier ALTER COLUMN id SET DEFAULT nextval('lookup.carrier_id_seq');

-- Reset sequence based on max(id) from lookup.carrier
SELECT setval(
   'lookup.carrier_id_seq',
   (SELECT COALESCE(MAX(id), 0) + 1 FROM lookup.carrier),
   false
);




-- Create a sequence if not exists
DO $$
BEGIN
   IF NOT EXISTS (SELECT 1 FROM pg_class WHERE relname = 'carrier_id_seq') THEN
      CREATE SEQUENCE carrier_id_seq OWNED BY carrier.id;
   END IF;
END$$;

-- Make id use sequence
ALTER TABLE carrier ALTER COLUMN id SET DEFAULT nextval('carrier_id_seq');


SELECT setval('carrier_id_seq', (SELECT COALESCE(MAX(id), 0) + 1 FROM carrier), false);
SHOW search_path;
SET search_path TO Schema1, public;
select 
json_event->'project',
json_event->'pipeline_params'->'artifacts_iac' as iac
from cicd_event
where event_type = 'ci_start'
and jsonb_array_length(jsonb_path_query_array(
	json_event->'pipeline_params'->'artifacts_iac',
	'$[*] ? (@.classifier == "terraform")'
)) >=2
//show images
docker images

//show volumes
docker volume ls

//check if the volume is attached to any container:
docker ps -a --filter volume=<volume_name>
  
// remove volume
docker volume rm <volume_name>
  
//automatically delete unused volumes
docker volume prune

//upack mongo.tar with volume to the directory
tar -xvf mongo.tar -C /path/to/mongo-data

//run docker container from image with attached volume
//mongodb_dm - volume name
//mongo - container name
docker run -d --name mongo -v mongodb_dm:/data/db -p 27017:27017 mongo:latest
docker run -d --name mongo -v mongodb_dm:/data/db -p 27017:27017 mongo:4.4
// with attached volume
docker run -d --name mongo -v /path/to/mongo-data:/data/db -p 27017:27017 mongo:4.4
docker run -d --name mongo -v mongo:/data/db -p 27017:27017 mongo:4.4

// run shel inside the container
docker exec -it mongo mongo
// with attached volume and auth
docker run -d --name mongo -v /path/to/mongo-data:/data/db -p 27017:27017 mongo:4.4 --auth
docker exec -it mongo mongo -u "admin" -p "yourpassword" --authenticationDatabase "admin"

docker inspect <container_id>

//enter into container
docker exec -it <container ID> bash

//build daemon
docker-compose up --build -d

docker stop <container ID>
docker rm <container ID>


//postgres with attached volume(directory)
docker run -d --name postgres -e POSTGRES_USER=<user> -e POSTGRES_PASSWORD=<password> -p 5432:5432 -v /path/to/postgres:/var/lib/postgresql/data postgres:14


SELECT 
  indexname AS index_name,
  tablename AS table_name,
  indexdef AS index_definition
FROM 
  pg_indexes
WHERE 
  schemaname = 'public'; -- Replace 'public' with the desired schema name if the index is in a different schema
def groovyObject
String json

// Groovy -> JSON
import groovy.json.JsonOutput
json = JsonOutput.prettyPrint(JsonOutput.toJson(groovyObject))

// Quick println
println groovy.json.JsonOutput.prettyPrint(groovy.json.JsonOutput.toJson(groovyObject))

// JSON -> Groovy
import groovy.json.JsonSlurper
def jsonSlurper = new JsonSlurper()
groovyObject = jsonSlurper.parseText(json)
SELECT
    planname,
    '{"c":"baz"}'::JSON,
    json_build_object(planname,1,'bar',2)
FROM bplaene
LIMIT 10
;

-- Complex nested JSON with arrays
SELECT json_build_object(
               'trans_id', t.trans_id,
               'user_data', json_build_object(
                       'user_id', t.user_id,
                       'user_username', t.user_username,
                       'user_full_name', t.user_full_name,
                       'user_street', t.user_street,
                       'user_postal_code', t.user_postal_code,
                       'user_additional_info', t.user_additional_info,
                       'user_country', t.user_country,
                       'user_vat_number', t.user_vat_number),
               'order_data', json_build_object(
                       'order_date', t.order_date,
                       'order_sum', t.order_sum,
                       'order_vat', t.order_vat,
                       'order_invoice_nr', t.order_invoice_nr
                   ),
               'locations',
               (SELECT json_agg(row_to_json(locations))
                FROM (SELECT l.address,
                             l.project_title,
                             (SELECT json_agg(row_to_json(f))
                              FROM (SELECT layername,
                                           data
                                    FROM sales.features) f) features

                      FROM sales.locations l) locations)
           ) transaction
FROM sales.transactions t
select 
  case greatest(col1,col2,col3,col4) 
    when col1 then 'col1:' || col1
    when col2 then 'col2:' || col2
    when col3 then 'col3:' || col3
    when col4 then 'col4:' || col4
    else null
  end as greatestcolumnname
from mytable;
sudo -u postgres psql
create database mydb;
create user myuser with encrypted password 'mypass';
grant all privileges on database mydb to myuser;
$ psql -h <host> -p <port> -U <username> <database>
select "field1", "field2", count(*)
from "tableName"
group by "field1", "field2"
HAVING count(*) > 1
  
create or replace function decode_url(url text)
  returns text as
$BODY$
DECLARE result text;
BEGIN
    if url isnull then
        return null;
    end if;

    BEGIN
        with str AS (
            select
                   case when url ~ '^%[0-9a-fA-F][0-9a-fA-F]'
                   then array['']
                   end
            || regexp_split_to_array(url, '(%[0-9a-fA-F][0-9a-fA-F])+', 'i') plain,

            array(select (regexp_matches(url, '((?:%[0-9a-fA-F][0-9a-fA-F])+)', 'gi'))[1]) encoded
            )

        select string_agg(plain[i] || coalesce(convert_from(decode(replace(encoded[i], '%',''), 'hex'), 'utf8'),''),'')
        from str, (select generate_series(1, array_upper(encoded, 1) + 2) i FROM str) serie
        into result;

    EXCEPTION WHEN OTHERS THEN
        raise notice 'failed: %', url;
        return url;
    END;

    return coalesce(result, url);

END;

$BODY$
  LANGUAGE plpgsql IMMUTABLE STRICT;
CREATE OR REPLACE
FUNCTION table_has_column(tablename TEXT,
OUT res boolean)
 RETURNS boolean

AS $func$
-- DECLARE res boolean DEFAULT FALSE;

BEGIN
SELECT
    (count(constraint_name)>0)::boolean AS res
INTO
    res
FROM
    information_schema.table_constraints
WHERE
    table_name = tablename
    AND constraint_type = 'PRIMARY KEY';
END;

$func$ LANGUAGE plpgsql;

CREATE OR REPLACE
FUNCTION table_has_pk(tablename TEXT,
OUT res boolean) RETURNS boolean AS $func$ 
res boolean DEFAULT FALSE;

BEGIN
SELECT
    (count(constraint_name)>0)::boolean AS res
INTO
    res
FROM
    information_schema.table_constraints
WHERE
    table_name = tablename
    AND constraint_type = 'PRIMARY KEY';
END;

$func$ LANGUAGE plpgsql;

CREATE OR REPLACE
FUNCTION table_has_column(tablename TEXT,
columnname TEXT,
OUT res boolean)
 RETURNS boolean
 
AS $func$ 

BEGIN
SELECT
    (count(column_name) > 0)::boolean AS res
INTO
    res
FROM
    information_schema.columns
WHERE
    table_name = tablename
    AND column_name = columnname;
END;

$func$ LANGUAGE plpgsql;

CREATE OR REPLACE
FUNCTION table_has_columns(tablename TEXT,
VARIADIC columnname TEXT) RETURNS boolean AS $func$
 DECLARE res boolean DEFAULT FALSE;

DECLARE
  x TEXT;

res boolean DEFAULT TRUE;

BEGIN
  FOREACH x IN ARRAY columnname LOOP
      EXIT
WHEN res = FALSE;

SELECT
    table_has_column(tablename,
    x) AS res
INTO
    res;
END;
END;

$func$ LANGUAGE plpgsql;
grant all privileges on database <dbname> to <username> ;
select pgc.conname as constraint_name,
       ccu.table_schema as table_schema,
       ccu.table_name,
       ccu.column_name,
       pgc.* as definition
from pg_constraint pgc
join pg_namespace nsp on nsp.oid = pgc.connamespace
join pg_class  cls on pgc.conrelid = cls.oid
left join information_schema.constraint_column_usage ccu
          on pgc.conname = ccu.constraint_name
          and nsp.nspname = ccu.constraint_schema
where contype ='c'
order by pgc.conname;
select users.last_login,us.*,users.* from users left join user_school us on us.user_id = users.id where school_id is not null
and last_login between '2021-01-01'::date and '2021-12-31'::date
UPDATE public.users
SET name=concat('User',id), email=concat('user',id,'@email.com')
WHERE name not like '%Testbruker';
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'dojoreads_db',
        'USER': 'postgres',
        'PASSWORD': 'root',
        'HOST': '127.0.0.1',
        'PORT': '5432',
    }
}
star

Tue Oct 14 2025 06:56:26 GMT+0000 (Coordinated Universal Time)

#postgres
star

Fri Oct 10 2025 18:18:17 GMT+0000 (Coordinated Universal Time)

#postgres
star

Thu Oct 09 2025 16:27:31 GMT+0000 (Coordinated Universal Time)

#postgres
star

Tue Sep 23 2025 13:07:53 GMT+0000 (Coordinated Universal Time)

#postgres
star

Fri Jul 12 2024 11:02:41 GMT+0000 (Coordinated Universal Time)

#postgres #postgis #sql
star

Fri Jun 07 2024 13:57:08 GMT+0000 (Coordinated Universal Time)

#postgres #postgresql #json
star

Thu Apr 18 2024 19:38:43 GMT+0000 (Coordinated Universal Time)

#docker #mongodb #postgres
star

Tue Jul 25 2023 07:23:58 GMT+0000 (Coordinated Universal Time)

#sql #postgres
star

Mon Jun 19 2023 10:05:19 GMT+0000 (Coordinated Universal Time)

#postgres #postgresql #percentile #median #average #duration
star

Fri Mar 03 2023 10:57:14 GMT+0000 (Coordinated Universal Time)

#postgres #sql #json
star

Thu Mar 10 2022 03:28:53 GMT+0000 (Coordinated Universal Time) https://medium.com/coding-blocks/creating-user-database-and-adding-access-on-postgresql-8bfcd2f4a91e

#postgres
star

Mon Feb 14 2022 07:38:16 GMT+0000 (Coordinated Universal Time) https://alvinalexander.com/blog/post/postgresql/log-in-postgresql-database/

#login #postgres
star

Mon Feb 14 2022 07:24:44 GMT+0000 (Coordinated Universal Time) https://medium.com/ruralscript/install-and-setuppostgresql-on-ubuntu-amazon-ec2-5d1af79b4fca

#ec2 #postgres #setup-postgres-on-ec2 #ubuntu
star

Mon Feb 14 2022 07:02:20 GMT+0000 (Coordinated Universal Time)

#psql #postgres #remotedb
star

Mon Jan 03 2022 02:32:45 GMT+0000 (Coordinated Universal Time) https://stackoverflow.com/

#sql #postgres #duplicate
star

Mon Dec 06 2021 10:27:38 GMT+0000 (Coordinated Universal Time)

#sql #postgres
star

Thu Dec 02 2021 18:53:06 GMT+0000 (Coordinated Universal Time)

#sql #postgres #columns
star

Wed Jul 07 2021 17:00:07 GMT+0000 (Coordinated Universal Time) https://medium.com/coding-blocks/creating-user-database-and-adding-access-on-postgresql-8bfcd2f4a91e

#postgres
star

Mon Jun 14 2021 17:06:09 GMT+0000 (Coordinated Universal Time)

#sql #postgres
star

Fri May 28 2021 15:01:34 GMT+0000 (Coordinated Universal Time)

#sql #postgres
star

Thu May 27 2021 20:27:23 GMT+0000 (Coordinated Universal Time)

#sql #postgres
star

Mon Mar 29 2021 22:54:38 GMT+0000 (Coordinated Universal Time)

#python #django #postgres
star

Mon Mar 29 2021 22:20:07 GMT+0000 (Coordinated Universal Time)

#python #django #postgres

Save snippets that work with our extensions

Available in the Chrome Web Store Get Firefox Add-on Get VS Code extension