7 puntos por GN⁺ 2023-06-28 | 1 comentarios | Compartir por WhatsApp
  • ORM suele recibir críticas como “un juguete para startups”, pero el punto real se parece más a una forma incorrecta de usarlo que al ORM en sí
  • Los grafos de objetos y las tablas relacionales son modelos distintos, por lo que aparece un desajuste de paradigmas, pero eso por sí solo no basta para considerar al ORM un antipatrón
  • El debate sobre violaciones de SRP y SOC es válido, pero como el ORM es desde el principio una abstracción que conecta dos modelos de datos, es difícil juzgarlo solo por una posible violación de principios
  • Los problemas de rendimiento suelen surgir menos por el ORM que por patrones que combinan datos en la lógica del lenguaje anfitrión, y pueden reducirse con las funciones similares a SQL del ORM
  • La razón principal por la que Lago cambió consultas de Active Record a SQL crudo no fue la velocidad sino la visibilidad y depuración, y en consultas grandes pasar a SQL crudo puede ser una ventaja práctica

Postura básica ante las críticas al ORM

  • El ORM suele ser atacado como “antipatrón”, pero concluir que el ORM en sí es malo resulta exagerado
  • Como cualquier otra abstracción, el ORM tampoco es perfecto, y puede generar cierta pérdida de visibilidad y costo de rendimiento
  • Lago tuvo problemas mientras dependía de Active Record, el ORM de Ruby on Rails, y eso lo llevó a reconsiderar su forma de depender del ORM
  • La conclusión no es que haya que abandonar el ORM, sino más bien que debe tratarse como una abstracción con ventajas y desventajas muy claras

Diferencia entre el modelo de objetos y la base de datos relacional

  • Los objetos que maneja un ORM se parecen más a un grafo dirigido donde los nodos apuntan a otros nodos
  • Las tablas de una base de datos relacional se parecen más a un grafo no dirigido donde los datos se conectan en ambos sentidos mediante claves compartidas
  • Un ORM puede imitar un grafo no dirigido, pero su configuración y funcionamiento no siempre son simples
    • Al objeto User podría faltarle un arreglo Posts
    • Las entidades del arreglo Posts podrían no tener una referencia de regreso al mismo objeto User
    • Incluso si existe esa referencia de regreso, podría no ser el mismo objeto sino una copia
  • Por ejemplo, un ORM puede devolver las publicaciones de un usuario como un arreglo sin incluir en cada publicación una referencia inversa al usuario en su rol de autor
  • Este desajuste es una buena crítica académica al ORM, pero en producción los problemas mayores suelen aparecer en la forma concreta de uso

Debate sobre SRP y SOC

  • Principio de responsabilidad única (SRP)

    • Se critica al ORM por violar el principio de responsabilidad única (SRP)
    • Porque puede hacer que una clase o capa asuma varios papeles al mismo tiempo
      • ejecutar operaciones de base de datos y transacciones
      • representar registros
      • definir relaciones
      • generar y ejecutar migraciones
    • Pero como el propósito del ORM es precisamente conectar dos paradigmas de datos distintos, es difícil descartarlo solo por algunas violaciones de principios
  • Separación de intereses (SOC)

    • El ORM también puede difuminar el principio de separación de intereses (SOC)
    • SOC es el principio de que un componente de infraestructura debería tener una sola preocupación
    • Como el ORM traslada la administración de la base de datos hacia el backend, hay margen para verlo como una violación de SOC
    • Aun así, hoy en día los componentes de infraestructura y los patrones de código a veces combinan varios roles por rendimiento, latencia y organización del código
      • agregadores de CPU dentro de bases de datos OLAP
      • backends-frontends en el edge
      • monorepos

Los problemas de rendimiento suelen surgir más por la forma de uso que por el ORM

  • La crítica de que el ORM siempre es ineficiente es en general incorrecta
  • Muchos ORM pueden funcionar de manera mucho más eficiente de lo que los desarrolladores imaginan
  • El problema es que el ORM facilita combinar datos usando lógica del lenguaje anfitrión como JavaScript o Ruby
  • En el ejemplo de TypeORM, se considera un mal patrón consultar primero los autores de cierta empresa, luego volver a consultar las publicaciones de cada autor y después guardar cada publicación por separado
  • Una mejor forma es construir una sola consulta de actualización con createQueryBuilder() de TypeORM
  • En la refactorización del SQL de facturación de Lago tampoco hubo diferencia de rendimiento entre la versión con Active Record y la versión en SQL crudo
    • Como ya usaban bastante las funciones de combinación de datos de Active Record, la consulta existente ya estaba optimizada
    • Reescribirla en SQL crudo tuvo más que ver con ganar visibilidad que con mejorar el rendimiento

Casos en los que el ORM sí puede volverse lento

  • El ORM no siempre es tan eficiente como el SQL crudo, y en algunas situaciones puede ser bastante ineficiente
  • El primer problema es que al convertir resultados de consultas en objetos, el ORM puede generar una gran sobrecarga computacional
    • Se menciona a TypeORM como ejemplo de este problema
  • El segundo problema aparece al recorrer relaciones de uno a muchos o de muchos a muchos, enviando múltiples solicitudes de ida y vuelta a la base de datos
  • Este patrón se conoce como el problema N+1
    • a la consulta original se le agregan N subconsultas
    • en el ejemplo de Prisma, al consultar de forma anidada usuarios, publicaciones y comentarios, podría generarse una nueva solicitud a la base de datos por cada comentario
  • N+1 aparece con frecuencia en ORM, pero con un data loader se pueden reducir N+1 consultas a solo 2
  • Una parte importante de los problemas típicos del ORM puede evitarse si se aprovechan bien sus funciones

El problema mayor es la visibilidad y la depuración

  • La mayor debilidad del ORM es la visibilidad
  • En la práctica, el ORM es un generador de consultas, así que salvo errores obvios como fallas de tipos primitivos, no es el emisor final del error
  • Cuando vuelve un error de SQL, el ORM tiene que interpretarlo y reenviarlo al usuario
  • Active Record tuvo dificultades en este punto, y esa fue también la razón por la que Lago refactorizó su consulta de suscripciones de facturación
  • Cuando los resultados no coincidían con lo esperado, había que repetir el siguiente proceso
    • revisar la consulta SQL renderizada
    • volver a ejecutar ese SQL
    • traducir el error de SQL de nuevo a cambios en Active Record
  • Este ir y venir debilitaba el propósito original de usar Active Record para no interactuar directamente con la base de datos SQL

Criterio práctico

  • Si se usa correctamente, el ORM puede lograr una eficiencia cercana a la del SQL crudo
  • Muchos problemas surgen cuando no se usan las funciones similares a SQL del ORM y se depende demasiado de la estructura lógica del lenguaje anfitrión
  • Si las consultas grandes complican a los desarrolladores y obstaculizan la depuración, moverlas a consultas SQL crudas puede ser una buena inversión
  • La mayoría de los ORM ofrecen funciones para ejecutar consultas SQL desde dentro del propio ORM

1 comentarios

 
GN⁺ 2023-06-28
Opiniones de Hacker News
  • He usado ORM desde que Hibernate acababa de salir en Java, pero siempre me parecieron malos
    La ventaja de “poder cambiar a otra base de datos” hoy suena casi a tontería, y en la práctica nadie los usa así
    Eso de “no hace falta saber SQL” también es falso, y cualquier app no trivial que dure en el tiempo termina necesitando ajustar consultas individuales a nivel de cadenas
    La capa de datos debería construirse consulta por consulta con SQL en cadenas e interpolación; en mi opinión, cuanto más cerca de raw JDBC, mejor
    La afirmación de que los ORM dan soporte a un “modelo de dominio” también es una mala razón, porque ese modelo de dominio siempre termina siendo un modelo de dominio anémico, sin lógica
    Me dan ganas de llorar al pensar en el tiempo desperdiciado en ORM, XML, anotaciones, depuración de SQL generado, etc.

    • Totalmente de acuerdo. Yo diría que los ORM “hacen que las partes fáciles sean un poco más fáciles, pero hacen que las partes difíciles sean realmente difíciles”
      Las partes fáciles ya eran fáciles, así que no me interesan mucho; en cambio, muchas veces, en el peor momento, cuando una consulta se cae al encontrarse con la escala, el trabajo se volvió un millón de veces más difícil por tener que pelearme con el propio ORM
      Un query builder no es exactamente lo mismo que un ORM, pero me gusta el artículo https://gajus.medium.com/stop-using-knex-js-and-earn-30-bf41... y me volví fan de tecnologías tipo Slonik
      Ofrecen el 90% de las funciones que quiero, como enlazar automáticamente los resultados a objetos y hacer verificación fuerte de tipos, pero aun así me dejan escribir SQL común y corriente
      Tampoco entiendo la idea de que SQL sea un lenguaje misteriosamente difícil. Es viejo y tiene sus defectos, pero prefiero aprender SQL antes que aprender el lenguaje de consultas propio que inventó una herramienta ORM
    • Desde que los probé por primera vez hace mucho tiempo, odié los ORM por las mismas razones y los vi como un antipatrón
      En ese entonces, cuando decía estas críticas, otros desarrolladores solían mirarme por encima del hombro
      Incluso hoy, muchas de las herramientas y técnicas que uno se ve obligado a usar como desarrollador son antipatrón, y la triste realidad de la industria es que una buena parte de las herramientas más usadas son mediocres y fomentan antipatrones
      En la industria tecnológica hay un pequeño grupo de desarrolladores y exdesarrolladores bien conectados que toman decisiones, y me parecen malos
    • Resulta que empezaste justo con uno de los peores ORM que existen
      Hay ORM con una relación aceptable entre ventajas y desventajas, y los de Python en particular son buenos
      El ORM de Django es tosco y su rendimiento no es gran cosa, pero está bien integrado, es práctico, productivo y agradable de usar
      Peewee ofrece un ORM en un paquete pequeño, y permite escribir programitas con gusto cuando no necesitas funciones sofisticadas y no quieres complicarte
      SQLAlchemy requiere más inversión, pero es muy flexible, genera SQL limpio y se comporta correctamente
      También expone un query builder de menor nivel para cuando no quieres el paradigma orientado a objetos y prefieres expresar en Python una abstracción del comportamiento idiomático de SQL
      Al final, se vuelve una decisión común de ingeniería sobre retorno de la inversión
    • Eso de que “hay que ajustar a nivel de cadenas” es, según mi experiencia, una tontería
      Llevo más de 10 años haciéndolo, y nunca he visto una consulta que no pudiera manejarse mejor leyendo 5 minutos la documentación de Hibernate y haciendo lo que recomienda para esa situación
      Parece que los fanboys de SQL, que creen que todos los desarrolladores deben memorizar tablas de lógica ternaria y nombres de funciones al estilo COBOL, no quieren tomarse el trabajo de leer la documentación de Hibernate
    • Ninguna persona con un mínimo de criterio ha presentado jamás “no hace falta saber SQL” como una ventaja de un ORM
      Los ORM son para cargas de trabajo OLTP, no para OLAP, y uno de los creadores de Hibernate también lo ha dicho
      Su utilidad principal es evitar tener que escribir a mano consultas INSERT/UPDATE largas y propensas a errores, y mapear automáticamente filas SQL a objetos
      Si vas por el camino raw, terminas reimplementando buena parte de eso, así que tampoco es un juego de suma cero
  • En una app lo suficientemente compleja, tarde o temprano aparece algo como un query builder que permite que varias partes de la app compongan consultas de forma diferida
    Es una estructura en la que, en vez de combinar, filtrar y ordenar datos en memoria, se componen como una consulta
    Un ORM puede ser una herramienta que facilita esto, pero también puede hacer que te pegues un tiro en el pie al facilitar crear consultas N+1 sin darte cuenta
    Como con toda herramienta, hay que evaluar los trade-offs junto con los casos de uso reales, y manipular directamente strings de sentencias SQL no es recomendable en ningún caso

    • La experiencia con un ORM puede variar de forma extrema según el lenguaje usado, el nivel de integración y el tipo de trabajo
      Aun así, siempre hay gente que ignora esas diferencias y afirma en términos absolutos que los ORM son buenos o malos
      Es mejor tomar eso como una postura polémica para llamar la atención y seguir de largo; preferiría concentrarme en discusiones que partan de “un ORM tiene beneficios, pero hay que saber dónde son válidos y evitar que los problemas de uso superen esos beneficios”
    • No doy por sentado que una app lo suficientemente compleja vaya a necesitar un query builder, y no lo aceptaría en mi app
      Si se necesitan datos, se va a la capa de acceso a datos; si no provee lo necesario, se crea un nuevo repositorio, proveedor o lo que corresponda al patrón
      Ya sea un ORM o un combinador de consultas hecho a mano, si la app llega al punto de creer que “es lo suficientemente compleja como para necesitar esto”, entonces ya se volvió demasiado compleja para usarlo de forma estable
      Al final terminas evaluando el builder en la capa equivocada, o se te escapa que estás creando consultas N+1 al iterar sobre los resultados
      No se necesita un ORM
    • Creo que esto se parece bastante a lo que hace LINQ, presentado en 2007
      LINQ no es exactamente un ORM: si creas sentencias LINQ fuertemente tipadas, se convierten en árboles de expresiones, y luego un proveedor de consultas las transforma en una consulta
    • Como alguien que usa tanto ORM como SQL raw, empatizo con ambos lados
      Durante el desarrollo prefiero la legibilidad del ORM dentro del modelo, pero vigilo de cerca y optimizo N+1 y otras ineficiencias cuando hace falta
      El límite de “cuando hace falta” no es claro, pero intento no optimizar demasiado temprano
      En proyectos nuevos suelo empezar por la base de datos y, antes de programar, me hago una idea del modelo de datos con factories, seeders y consultas SQL raw
      Los ORM como Eloquent de Laravel tienen buenos métodos para resolver N+1 y realizar carga diferida, pero siempre hay trade-offs
    • También hay librerías que invierten el concepto de ORM
      En lugar de una librería que permite componer consultas de forma diferida, escribes la consulta directamente y la librería genera en tiempo de compilación el código para esa consulta
      Por ejemplo, si escribes una consulta como getUser: SELECT * FROM users WHERE id = ?, te genera una clase GetUserQuery y un método como getUser(id: String): GetUserQueryResult; me parece que este modelo es mucho mejor
  • La principal razón por la que no me gustan los ORM es su tendencia a tratar los motores SQL modernos como almacenes tontos de bits exagerados
    Aunque los CTE, los joins LATERAL y las cláusulas RETURNING pueden simplificar mucho el procesamiento o eliminar la posibilidad de inconsistencias de datos, los ORM suelen quedarse en el nivel de mapear tablas base y vistas a objetos predefinidos
    Si el ORM además crea las tablas, peor todavía
    SQL es, en esencia, una herramienta de extracción de datos y también un lenguaje de transformación, pero los ORM casi ignoran este aspecto, por lo que muchos desarrolladores no saben qué hay en SQL además de INSERT/SELECT/UPDATE/DELETE
    Hay tablas dinámicas, consultas temporales, CUBE/ROLLUP, funciones de ventana, funciones que devuelven conjuntos, vistas materializadas, tablas externas, procesamiento de JSON, manejo de fechas, restricciones de exclusión, tipos como rangos, intervalos y dominios, seguridad a nivel de fila, MERGE, etc.
    Es como tener un taller completo de herramientas y que alguien te entregue solo un martillo, un destornillador y una sierra para metales mientras te convence de que eso basta, y pasarte la carrera sin saber que a unos metros hay una sierra de mesa, un router, una lijadora y un juego de cuñas

    • La mayoría de los frameworks ORM tienen funcionalidad para ejecutar SQL raw, así que usar un ORM no significa que no puedas usar esas funciones
      Los ORM hacen que uno piense sobre todo en sentencias CRUD simples, pero probablemente eso sea mejor, y creo que las funciones avanzadas deberían usarse con moderación
    • Siento que tengo suerte porque trabajo principalmente en proyectos sin base de datos
      Aun así, cuando tengo que usar una DB, intento usar deliberadamente solo un subconjunto muy pequeño de las funciones de la DB
      Porque veo el “código” como un área que puedo controlar, y la “base de datos” como un área peligrosa y difícil de alcanzar, cuyos errores aparecen después en lugares como pruebas de integración lentas
      La lógica que ocurre dentro de la DB queda fuera del alcance de las pruebas de bajo nivel y me asusta; probablemente ni siquiera usaría una consulta select-from-select
      Con gusto dejaría sin usar la mayor parte del taller de herramientas
    • Por eso no sorprende que muchos desarrolladores no vean la diferencia entre SQL y NoSQL
    • A medida que crece la escala, es común desnormalizar fuertemente la base de datos por motivos de rendimiento y usarla como un almacén tonto de bits exagerado
    • He trabajado en varios proyectos donde decían “no necesitamos esas funciones sofisticadas de la base de datos”, y fue frustrante lidiar con las consecuencias
      Terminas pasando la mayor parte del tiempo creando workarounds elaborados para reinventar protecciones básicas de integridad de datos
      Crear tu propia base de datos puede ser divertido para aprender, pero no para una app en producción
  • ActiveRecord siempre me pareció bueno
    Aunque hay algunos casos excepcionales, acierta muy bien con el punto 80/20; puedes escapar a SQL cuando hace falta, y sus hooks de ciclo de vida para ordenar la lógica de dominio son excelentes y fáciles de entender
    Me gustan los ORM pragmáticos que no esconden todo detrás de “bundles” ni introducen su propio lenguaje de consultas
    Los ORM que intentan “resolver” por completo el problema de los ORM son los difíciles de manejar

    • ActiveRecord es realmente agradable de usar, y cuando te encuentras con edge cases siempre puedes volver a SQL raw
      Así es como deberían hacerse los ORM
    • Es difícil imaginar volver a crear una gran app CRUD sin ActiveRecord; la legibilidad y la mantenibilidad serían peores
      Eso sí, para usarlo correctamente se necesita buen conocimiento previo de SQL
      Los problemas aparecen cuando la gente no aprende SQL y no entiende las consultas que genera AR ni sus límites
    • No entiendo muy bien las quejas sobre los ORM, aunque quizá sea porque el único ORM que he usado es ActiveRecord
  • La premisa es incorrecta. Un ORM nunca fue una “idea dañina”
    Hay ORM con los que es terrible trabajar, pero eso no significa que todo el género sea una mala idea
    He usado SQLAlchemy con gusto durante años porque no intenta reinventar el concepto mismo de SQL
    En cambio, ofrece una capa cómoda para construir y pasar consultas, y maneja correctamente los detalles pequeños para que no tengas que andar ajustándolos a mano

    • Mi experiencia con ORM es casi solo con SQLAlchemy, y apenas aprendí un poco de Ecto, así que al ver este hilo me pregunto si todos los demás ORM son horribles
      Últimamente, al aprender Rust, escribir a mano código repetitivo para CRUD simple se siente doloroso y una pérdida de tiempo
      El ORM de SQLAlchemy puede estorbar un poco en consultas más complejas o cuando se busca optimizarlas, pero en esos casos siempre puedes bajar directamente a SQL
    • Hacía muchísimo que no veía usar correctamente la expresión “begging the question”
    • SQLAlchemy es recomendable porque te permite escribir SQL con confianza, de una forma en que el código encaja con la consulta
  • Como con cualquier cosa, hay situaciones en las que encaja bien y otras en las que no, y la tecnología puede abusarse o usarse mal fácilmente
    Por ejemplo, un ORM como Entity Framework de .NET puede ser un gran activo, sobre todo cuando se trabaja con un enfoque database-first
    Si tienes una BD con cientos de tablas y relaciones de claves foráneas correctas, un ORM ayuda a explorar un esquema complejo y ofrece verificaciones en tiempo de compilación cuando hay cambios
    El SQL embebido es un arma de doble filo que puede parecer una ventaja de rendimiento, pero es muy difícil mantener SQL extenso y hardcodeado, especialmente en los joins
    No hablo de cuando hay 5 a 10 tablas, sino de cuando hay cientos
    No intento convencer a nadie, pero no hay que creer ciegamente lo que se lee en internet sobre buenas prácticas
    Las personas pueden estar hablando de cosas completamente distintas, y uses la tecnología que uses, siempre habrá desarrolladores malos

  • Si no usas un ORM u otra interfaz de BD, al final terminas escribiendo y manteniendo una por tu cuenta para cosas como CRUD
    Y es muy probable que dentro de eso haya bugs raros, casos borde y agujeros de seguridad
    También hay un problema con que en cursos universitarios se enseñen principios como SOLID como principios de diseño de software
    En la academia puede tener sentido, porque restricciones como tiempo, mantenibilidad, dinero y esfuerzo importan menos, pero cuando un recién graduado entra al mundo laboral se produce un choque muy malo
    Porque está acostumbrado a pasarse todo el día “afeitando yaks” y reinventando la rueda en busca de la solución “perfecta”
    Si no hay suficientes desarrolladores senior/lead competentes que pongan eso bajo control, terminas con productos muy interesantes, presupuestos excedidos, incendios enormes, o alguna combinación de todo eso
    Peor aún es cuando algo creado por la academia y diseñado para la academia se libera al público
    Un buen/mal ejemplo representativo es OpenStack: tiene tantas perillas y puntos de ajuste, y sus componentes están modularizados de forma demencial para soportar los entornos especiales de CERN y cientos de universidades, pero es tan bizantino que empezar es casi imposible

    • En este hilo hay muchas quejas de que los ORM no cumplen con las promesas de sus proveedores, y eso es cierto
      Un ORM no te cambia la base de datos sin esfuerzo, no elimina la necesidad de aprender y entender el SQL que genera, ni hace que el esquema sea impecable
      Aun así se usan porque son una abstracción estándar que, de todos modos, tendrías que replicar
      Permiten cachear el acceso a la BD, algo que con SQL manual se vuelve sorprendentemente difícil a medida que aumenta la escala
      Vienen con herramientas estandarizadas y buenas prácticas que pueden volver irrelevantes problemas como N+1
      El principal problema de los ORM son las expectativas equivocadas y los ORM malos
      Si quieres entender el valor de un ORM, abre un proyecto escrito sin ORM y cambia cualquier cosa
    • “Al final terminas haciendo uno tú mismo” solo es cierto si insistes en organizar la lógica en torno a objetos y no a “filas”
      Ver https://news.ycombinator.com/item?id=36498583
    • Algunos departamentos y varias empresas sufrieron o fracasaron porque una o unas pocas personas supergeniales perseguían la perfección
      No avanzaba nada útil, o tardaba entre 20 y 100 veces más que un enfoque rápido y sucio
      Lo peor fue un equipo de diseñadores HTML experimentados obligados a aprender programación funcional
      El asistente de configuración del backend era una maravilla de la ingeniería moderna y del diseño elegante, pero tomó 10 personas durante 1 año construirlo
      El dinero de VC vuelve rara a la gente
    • Había escuchado tantas cosas negativas sobre SQLAlchemy que decidí crear mi propio query builder ligero, pero 8 meses después terminé usando SQLAlchemy
      El lenguaje SQL es muy complejo, y crear un query builder completo y correcto, con todas las funcionalidades, no es para nada trivial
      Incluso dejando de lado la parte real del mapeo relacional
    • Es mejor usar un buen ORM; de lo contrario, terminarás cargando tú mismo con la mitad de un ORM pésimo
  • SQL es un caso en el que aplica “simplemente programa la maldita cosa directamente”
    No tiene mucho sentido aprender SQL o una biblioteca ORM; es mejor aprender y escribir SQL directamente
    El acceso a bases de datos probablemente será una tarea fundamental durante toda tu carrera, así que lo mejor es aprender la tecnología real de primera mano
    Con CSS pasa algo parecido: en vez de aprender una biblioteca de CSS, hay que aprender y usar CSS
    De hecho, casi todos los aspectos del desarrollo frontend son así; en lugar de una “biblioteca de formularios”, puedes manejar directamente la API de formularios del navegador
    Personalmente, SQL me resultó mucho más fácil de aprender que cualquier ORM
    No hay que desperdiciar el costo de aprender lo equivocado

    • Si aprendes SQL primero, también sabrás cuándo conviene usar un ORM y podrás evaluarlos mejor
      Con CSS pasa lo mismo: si sabes CSS, cuando elijas una biblioteca por comodidad tendrás mucha más flexibilidad y entenderás mucho mejor lo que haces
    • A SQL se lo ha llamado un lenguaje eterno
      A través de mainframes, escritorios, cliente/servidor, la web y muchas plataformas de desarrollo con sus distintos lenguajes encima, SQL siempre ha sido un hilo común
      Estoy totalmente de acuerdo en que un desarrollador que conoce bien la capa de datos y lo que ocurre debajo de ella es un desarrollador más fuerte
      Está la pregunta clásica: si vas a dedicar tiempo a aprender las particularidades de un ORM, ¿por qué no invertir ese tiempo en aprender SQL?
      El interés compuesto de la experiencia en SQL probablemente valga más dentro de 10 o 15 años que el ORM de una plataforma o lenguaje específicos
      Hay motivos para aprender y usar un ORM, pero no está bien inclinarse por un ORM solo porque no quieres aprender SQL
    • El punto central se parece más a “aprende los fundamentos primero antes de aprender la abstracción”
      Así sabrás qué estás pagando a cambio de esa abstracción. Claro, sería distinto si fuera una “abstracción sin costo”
    • Desde 1992 he escrito SQL directamente con Pro*Pascal y CS130
      Pero ahora, por el marshaling/unmarshaling con tipos de Go, estoy usando crud de azer, que podría clasificarse como ORM
      La biblioteca estándar sql de Go es tan básica que en la práctica tienes que escribir tú mismo el marshaling/unmarshaling de objetos, y es realmente tedioso
      Si hoy usara un ORM, creo que sería solo para ese propósito
  • Me gustan los micro ORM de “punto intermedio” como Dapper o Diesel
    Escribes las consultas en SQL, pero obtienes tipado fuerte y mapeo automático de los conjuntos de resultados a objetos
    Es decir, obtienes productividad junto con un lenguaje de consultas “real” y con todas las funciones
    También me empezó a gustar usar el mapper de objetos solo para consultas de solo lectura
    Las actualizaciones se hacen con el patrón de comandos, es decir, con procedimientos almacenados, y pueden mapearse para que parezcan métodos nativos

    • Dapper ha sido la solución de acceso a datos más agradable que he usado hasta ahora
      Los desarrolladores no deberían fingir que SQL no existe; deberían simplemente aceptarlo
    • Me gusta no tener que escribir a mano funciones de modelo que al final solo se mapean a SQL, ni boilerplate de PHP comercial para hacer correctamente consultas parametrizadas
      Eloquent abstrae lo suficiente de esas tareas tediosas como para poder concentrarse en la lógica
      Estoy reescribiendo una app PHP “vieja”, hecha solo con arreglos y consultas, hacia una estructura que usa modelos y Eloquent, y se siente como un cambio total de juego
    • Me gusta el punto intermedio. En TypeScript están, por ejemplo, Kysely o mi proyecto Zapatos
    • Creo que este es el punto óptimo
      Hace tiempo, cuando usaba SQLite en .NET, también hice una biblioteca envoltorio en esa dirección: https://github.com/zmj/sqlite-fast
  • Este hilo muestra bien el dominio de mindshare de los ORM
    En casi todos los comentarios, la alternativa implícita a un ORM es SQL raw como literales de cadena dentro del código de la app
    Ya desde hace 6 años existían herramientas que usan SQL como un lenguaje y generan wrappers que exponen las consultas como métodos en la app
    Cosas como queryfirst, pgtyped, pugsql y sqlc
    Esto es, o al menos podría haber sido, un cambio de paradigma, y se ve claramente que es una forma de trabajar superior; pero esta discusión inmutable sobre los ORM absorbe todo el oxígeno y lo mantiene en los márgenes

    • Exacto. En Go también está sqlc
      SQL es un lenguaje, y además uno de muy alto nivel
      Intentar concatenar SQL desde un lenguaje de más bajo nivel es un ejemplo clásico de “si tienes un martillo, todo parece un clavo”
      Por ejemplo, imagina que programas en assembly, que es de bajo nivel, y necesitas interactuar con un sistema grande cuya documentación dice que las entradas solo pueden expresarse en JavaScript. Tienes opciones
      Podrías traer una biblioteca esotérica que te permita concatenar algo en assembly puro y no commitear archivos xxx.js en el repositorio, o simplemente podrías expresarlo en archivos .js usando el poder de un lenguaje de alto nivel
    • Después de usar sqlc en un proyecto, siento que no podría volver atrás
      Tienes una única fuente de verdad para las consultas SQL que estás usando y, como lo que realmente escribes y mantienes son las consultas en sí, optimizaciones como crear nuevos índices también se vuelven más fáciles
    • ActiveRecord siempre me pareció flojo, y arel, que construye consultas por dentro, siempre me gustó
      Poner una abstracción sobre cadenas de SQL raw es muy útil, pero fingir que las relaciones son objetos es una forma enredada y compleja de hacerlo
    • Enterprise Objects Framework de NeXT ya soportaba esto hace más de 25 años
      TopLink probablemente también lo hacía
      Así era como manejaba el mapeo entre procedimientos almacenados y entidades locales
    • Me da curiosidad saber qué herramientas son