framework docs postgresql elixir phoenix-framework ecto

postgresql - docs - github phoenix framework



Configuración de Phoenix Framework y Ecto para usar UUID: ¿cómo insertar el valor generado? (2)

EDITAR: He actualizado esta respuesta a Ecto v2.0. Puedes leer la respuesta anterior al final.

Ecto v2

El manejo de UUID en Ecto se ha vuelto mucho más sencillo desde la respuesta original. Ecto tiene dos tipos de ID :id y :binary_id . El primero es un ID entero como sabemos por las bases de datos, el segundo es un binario específico de la base de datos. Para Postgres, es un UUID.

Para tener UUID como claves principales, primero especifíquelos en su migración:

create table(:posts, primary_key: false) do add :id, :binary_id, primary_key: true end

Luego en su módulo de modelo (fuera del bloque de schema ):

@primary_key {:id, :binary_id, autogenerate: true}

Cuando especifique la opción :autogenerate para :binary_id , Ecto garantizará que el adaptador o la base de datos lo generará por usted. Sin embargo, todavía puede generarlo manualmente si lo prefiere. Por cierto, podría haber usado :uuid en su migración y Ecto.UUID en su esquema en lugar de :binary_id , el beneficio de :binary_id es que es portátil en todas las bases de datos.

Ecto v1

Debe decirle a su base de datos cómo generar automáticamente el UUID para usted. O necesitas generar uno desde el lado de la aplicación. Depende de cuál prefieras.

Antes de continuar, es importante decir que está utilizando :uuid que devolverá los binarios en lugar de los UUID legibles. Es muy probable que desee utilizar Ecto.UUID que lo formateará como una cadena (aaaa-bbb-ccc -...) y eso es lo que usaré a continuación.

Generando en la base de datos

En su migración, defina un valor predeterminado para el campo:

add :id, :uuid, primary_key: true, default: fragment("uuid_generate_v4()")

Supongo que se está ejecutando en PostgreSQL. Debe instalar la extensión uuid-ossp con CREATE EXTENSION "uuid-ossp" en pgAdmin o agregar execute "CREATE EXTENSION /"uuid-ossp/"" en la migración. Más información sobre el generador UUID se puede encontrar aquí .

De vuelta a Ecto, en su modelo, pídale a Ecto que lea el campo de la base de datos después de insertar / actualizar:

@primary_key {:id, Ecto.UUID, read_after_writes: true}

Ahora, cuando inserte, la base de datos generará un valor predeterminado y Ecto lo leerá.

Generando en la aplicación

Deberá definir un módulo que inserte el UUID por usted:

defmodule MyApp.UUID do def put_uuid(changeset) do Ecto.Changeset.put_change(changeset, :id, Ecto.UUID.generate()) end end

Y utilízalo como devolución de llamada:

def model do quote do use Ecto.Model @primary_key {:id, Ecto.UUID, []} @foreign_key_type Ecto.UUID before_insert MyApp.UUID, :put_uuid, [] end end

before_insert es una devolución de llamada y llamará al módulo dado en la función dada con los argumentos dados, con un conjunto de cambios que representa lo que se inserta y se da como primer argumento.

Eso debería ser todo. Por cierto, existe la posibilidad de que esto sea más eficiente en el futuro. :)

Hace unos días comencé a usar Elixir y Phoenix Framework (v 0.12.0) con una base de datos de Postgres. Estoy tratando de crear una tabla que tenga una clave primaria UUID, que prefiero por encima del valor predeterminado secuencial.

Después de usar mix phoenix.gen.html para generar el modelo y los archivos de migración y seguir los otros pasos en los documentos de Phoenix, he cambiado

def model do quote do use Ecto.Model end end

en web.ex a

def model do quote do use Ecto.Model @primary_key {:id, :uuid, []} @foreign_key_type :uuid end end

como se menciona en los documentos ecto. También he cambiado la migración a

create table(:tblname, primary_key: false) do add :id, :uuid, primary_key: true [other columns] end

Desafortunadamente, cuando intento agregar una entrada a la tabla desde el formulario generado automáticamente, aparece un error porque el id es nulo. Si agrego manualmente una columna de id al modelo, recibo un error de que la columna ya existe. Si me olvido de establecer primary_key en falso en la table/2 y primary_key la columna de id , la tabla se genera con una columna de id secuencial.

¿Necesito configurar manualmente la id en el conjunto de cambios o he cometido un error al configurar mi aplicación para usar los UUID? Gracias por adelantado


También al crear una nueva opción de --binary-id proyecto --binary-id para usar UUID como clave principal predeterminada. (Iniciando Ecto v2 )

mix phx.new project_name --binary-id