क्या ORM अब भी anti-pattern है?
(github.com/getlago)- ORM को “स्टार्टअप्स का खिलौना” कहकर आलोचना की जाती है, लेकिन असली मुद्दा ORM खुद से ज्यादा उसके गलत इस्तेमाल के करीब है
- object graph और relational table अलग-अलग मॉडल हैं, इसलिए paradigm mismatch पैदा होता है, लेकिन सिर्फ इसी आधार पर ORM को anti-pattern कहना मुश्किल है
- SRP और SOC उल्लंघन वाली बहसें वैध हैं, पर ORM मूल रूप से दो data models को जोड़ने वाला abstraction है, इसलिए सिर्फ सिद्धांतों के उल्लंघन के आधार पर फैसला करना कठिन है
- performance समस्याएं ORM से ज्यादा अक्सर उस pattern से आती हैं जिसमें host language logic से data को जोड़-तोड़ कर assemble किया जाता है; इन्हें ORM की SQL-जैसी सुविधाओं से कम किया जा सकता है
- Lago ने Active Record queries को raw SQL में बदला, इसका मुख्य कारण speed से ज्यादा visibility और debugging था; बड़े queries में raw SQL पर जाना व्यवहारिक रूप से फायदेमंद हो सकता है
ORM आलोचना को देखने का बुनियादी नजरिया
- ORM पर अक्सर “anti-pattern” होने का हमला होता है, लेकिन ORM खुद खराब है—यह निष्कर्ष कुछ हद तक बढ़ा-चढ़ाकर कहा गया है
- दूसरे abstractions की तरह ORM भी perfect नहीं है, और कुछ visibility loss व performance cost पैदा कर सकता है
- Lago ने Ruby on Rails के ORM Active Record पर निर्भर रहते हुए समस्याएं झेलीं, और इसी वजह से ORM पर निर्भरता के तरीके की फिर से समीक्षा की
- निष्कर्ष ORM छोड़ देने की तरफ नहीं, बल्कि ORM को स्पष्ट फायदे-नुकसान वाले abstraction की तरह बरतने की तरफ ज्यादा है
object model और relational database का अंतर
- ORM जिन objects से निपटता है, वे दूसरे nodes की ओर इशारा करने वाले directed graph जैसे होते हैं
- relational database tables shared keys के जरिए data को दोनों दिशाओं में जोड़ने वाले undirected graph जैसे होते हैं
- ORM undirected graph की नकल कर सकता है, लेकिन उसका configuration और behavior हमेशा सरल नहीं होता
Userobject मेंPostsarray गायब हो सकता हैPostsarray की entities के पास उसीUserobject तक वापस जाने वाला reference न हो सकता है- वापस जाने वाला reference हो भी, तो वह वही object न होकर cloned object हो सकता है
- उदाहरण के लिए, ORM किसी user की posts को array के रूप में return कर सकता है, लेकिन हर post में author की भूमिका वाले user का back-reference शामिल न हो सकता है
- यह mismatch ORM पर एक अच्छी academic criticism है, लेकिन वास्तविक operations में बड़ी समस्या concrete usage patterns में दिखती है
SRP और SOC बहस
-
Single Responsibility Principle (SRP)
- ORM पर Single Responsibility Principle (SRP) तोड़ने की आलोचना होती है
- क्योंकि यह किसी एक class या layer को कई भूमिकाएं साथ में निभाने पर मजबूर कर सकता है
- database और transactions चलाना
- records का representation
- relationships define करना
- migrations बनाना और चलाना
- लेकिन ORM का उद्देश्य ही दो अलग data paradigms को जोड़ना है, इसलिए कुछ सिद्धांतों के उल्लंघन भर से ORM को नकारना मुश्किल है
-
Separation of Concerns (SOC)
- ORM Separation of Concerns (SOC) सिद्धांत को भी धुंधला कर सकता है
- SOC का मतलब है कि infrastructure component की सिर्फ एक concern होनी चाहिए
- ORM database management को backend की तरफ ले जाता है, इसलिए इसे SOC उल्लंघन के रूप में देखा जा सकता है
- हालांकि आजकल infrastructure components और coding patterns performance, latency और code organization के लिए कई भूमिकाओं को combine भी करते हैं
- OLAP database के अंदर CPU aggregator
- edge backend-frontend
- monorepo
performance समस्या अक्सर ORM से ज्यादा इस्तेमाल के तरीके से आती है
- ORM हमेशा inefficient होता है—यह आलोचना अधिकतर गलत है
- कई ORM developers की अपेक्षा से कहीं ज्यादा efficient तरीके से काम कर सकते हैं
- समस्या यह है कि ORM JavaScript या Ruby जैसी host language logic में data assemble करना आसान बना देता है
- TypeORM के उदाहरण में, पहले किसी खास company के authors को fetch करना, फिर हर author की posts को फिर से fetch करना, और हर post को अलग-अलग save करना एक खराब pattern माना गया है
- बेहतर तरीका TypeORM के
createQueryBuilder()से एक single update query बनाना है - Lago के billing SQL refactoring में भी Active Record और raw SQL versions के बीच performance difference नहीं था
- Active Record की data-combining capabilities का काफी उपयोग हुआ था, इसलिए पुरानी query पहले से optimized थी
- raw SQL rewrite performance improvement से ज्यादा visibility हासिल करने के लिए था
ORM सच में कब slow हो सकता है
- ORM हमेशा raw SQL जितना efficient नहीं होता, और कुछ स्थितियों में काफी inefficient हो सकता है
- पहली समस्या यह है कि query results को objects में बदलते समय ORM बड़ा computational overhead पैदा कर सकता है
- TypeORM को इस समस्या के उदाहरण के रूप में बताया गया है
- दूसरी समस्या तब आती है जब one-to-many या many-to-many relationships traverse करते हुए database को कई round-trip requests भेजी जाती हैं
- इस pattern को N+1 problem कहा जाता है
- original query 1 होती है और उसमें N sub-queries जुड़ जाती हैं
- Prisma के उदाहरण में users, posts और comments को nested तरीके से fetch करते समय हर comment के लिए नया database request हो सकता है
- N+1 ORM में अक्सर दिखता है, लेकिन data loader इस्तेमाल करने पर N+1 queries को 2 queries में समेटा जा सकता है
- ORM की कई सामान्य समस्याओं से ORM features का पर्याप्त उपयोग करके बचा जा सकता है
बड़ी समस्या visibility और debugging है
- ORM की सबसे बड़ी कमजोरी visibility है
- ORM असल में query builder होता है, इसलिए obvious raw type errors जैसे मामलों को छोड़कर यह final error messenger नहीं होता
- SQL error return होने पर ORM को उसे interpret करके user तक फिर से पहुंचाना पड़ता है
- Active Record को इस जगह परेशानी हुई, और Lago ने billing subscription query को refactor भी इसी वजह से किया
- जब अपेक्षा से अलग results आते थे, तो यह प्रक्रिया दोहरानी पड़ती थी
- rendered SQL query की जांच करना
- उस SQL को फिर से execute करना
- SQL error को वापस Active Record change में translate करना
- यह round-trip process उस मूल उद्देश्य को कमजोर कर देता है जिसके लिए SQL database से direct interaction से बचने हेतु Active Record इस्तेमाल किया जा रहा था
व्यावहारिक निर्णय
- ORM सही तरीके से इस्तेमाल करने पर raw SQL के करीब efficiency दे सकता है
- कई समस्याएं तब आती हैं जब ORM की SQL-जैसी सुविधाएं इस्तेमाल नहीं की जातीं और host language के logic structure पर बहुत ज्यादा निर्भरता रखी जाती है
- अगर बड़ी query developers के लिए मुश्किल बन रही है और debugging में बाधा डाल रही है, तो raw SQL query पर जाना अच्छा investment हो सकता है
- ज्यादातर ORM, ORM के अंदर SQL queries execute करने की सुविधा देते हैं
1 टिप्पणियां
Hacker News की राय
Java में Hibernate के बिल्कुल शुरुआती दिनों से ORM इस्तेमाल करता आया हूँ, लेकिन यह हमेशा खराब ही लगा
“दूसरे database में बदल सकते हैं” वाला फ़ायदा आज के हिसाब से लगभग बकवास लगता है, और असल में कोई इसे उस तरह इस्तेमाल नहीं करता
“SQL जानने की ज़रूरत नहीं” वाली बात भी गलत है, और लंबे समय तक चलने वाले non-trivial apps में आखिरकार अलग-अलग queries को string स्तर पर हाथ से ठीक करना ही पड़ता है
data layer में हर query को string SQL के रूप में बनाना और interpolate करना ही सही तरीका है, और मेरे हिसाब से raw JDBC के जितना करीब हो उतना बेहतर है
ORM “domain model” को support करता है, यह दावा भी खराब वजह है, क्योंकि वह domain model हमेशा logic से खाली anemic domain model बन जाता है
ORM, XML, annotations, generated SQL की debugging वगैरह में बर्बाद हुए समय को सोचकर रोना आता है
आसान हिस्से तो पहले से ही आसान हैं, इसलिए उनमें खास दिलचस्पी नहीं है; बल्कि सबसे बुरे समय में, जब query scale पर टूटने लगती है, ORM खुद से लड़ते-लड़ते काम दस लाख गुना मुश्किल हो जाता है
query builder ORM के बिल्कुल बराबर नहीं है, लेकिन मुझे https://gajus.medium.com/stop-using-knex-js-and-earn-30-bf41... लेख पसंद है और मैं Slonik जैसी तकनीक का प्रशंसक बन गया हूँ
यह results को objects में auto-bind करने और strong type checks देने जैसी मनचाही 90% सुविधाएँ देता है, फिर भी आपको सामान्य SQL ही लिखने देता है
मुझे यह भी समझ नहीं आता कि लोग SQL को कोई रहस्यमय और बेहद कठिन language क्यों मानते हैं। पुरानी है और कमियाँ हैं, लेकिन ORM tools की बनाई अपनी query language सीखने से बेहतर है SQL सीखना
उस समय ऐसी आलोचना करने पर दूसरे developers ऊपर से देखते थे
आज भी developer के रूप में जिन tools और techniques को मजबूरी में इस्तेमाल करना पड़ता है, उनमें anti-pattern बहुत हैं, और industry की दुर्भाग्यपूर्ण सच्चाई यह है कि व्यापक रूप से इस्तेमाल होने वाले काफ़ी tools घटिया हैं और anti-pattern को बढ़ावा देते हैं
tech industry में कुछ कम लोग हैं जिनके पास फैसले की ताकत है, वे अच्छी networking वाले developers और ex-developers हैं, और वे काफ़ी खराब लगते हैं
कुछ ORM ऐसे भी हैं जिनमें pros और cons का संतुलन ठीक है, खासकर Python की दुनिया में
Django ORM भद्दा है और performance भी खास नहीं, लेकिन इसकी integration अच्छी है, यह practical, productive है और इस्तेमाल करने में अच्छा लगता है
Peewee एक छोटे package में ORM देता है, इसलिए जब बहुत बड़ी सुविधाओं की ज़रूरत न हो और बस झंझट नहीं चाहिए, तब छोटे programs मज़े से लिखे जा सकते हैं
SQLAlchemy में ज़्यादा investment चाहिए, लेकिन यह बहुत flexible है, साफ़ SQL generate करता है और सही तरीके से काम करता है
अगर आपको object-oriented paradigm नहीं चाहिए और Python में idiomatic SQL behavior को abstract करके व्यक्त करना है, तो यह उसके लिए lower-level query builders भी expose करता है
आखिरकार यह return on investment को तौलने वाला एक सामान्य engineering decision बन जाता है
10 साल से ज़्यादा समय से यह कर रहा हूँ, लेकिन Hibernate के docs 5 मिनट पढ़कर और उसमें उस स्थिति के लिए जो कहा गया है वैसा करके, ऐसा कोई query नहीं मिला जिसे बेहतर तरीके से handle न किया जा सके
ऐसा लगता है कि हर developer को three-valued logic tables और COBOL-जैसे function names याद होने चाहिए, यह मानने वाले SQL fanboys खुद Hibernate docs पढ़ने की मेहनत नहीं करना चाहते
ORM OLTP workloads के लिए है, OLAP के लिए नहीं, और Hibernate के संस्थापकों में से एक ने भी यही कहा था
इसका मुख्य उपयोग बस इतना है कि लंबे और error-prone INSERT/UPDATE queries हाथ से न लिखने पड़ें, और SQL rows को अपने-आप objects में map कर दे
raw तरीके पर जाएँगे तो उसका बड़ा हिस्सा फिर से खुद implement करना पड़ेगा, इसलिए यह भी zero-sum game नहीं है
काफ़ी जटिल apps में, देर-सवेर query builder जैसी कोई चीज़ उभर आती है जहाँ app के अलग-अलग हिस्से मिलकर queries को lazily compose कर सकते हैं
यानी data को memory में जोड़ने, filter करने और sort करने के बजाय query के रूप में compose किया जाता है
ORM इसे आसान बनाने का एक tool है, लेकिन अनजाने में N+1 queries बनाना भी बहुत आसान कर देता है और वही उल्टा पड़ सकता है
हर tool की तरह, इसे भी वास्तविक use case के साथ trade-offs तौलकर देखना चाहिए, और SQL statement strings को सीधे manipulate करने का तरीका किसी भी स्थिति में recommend नहीं है
फिर भी हमेशा कुछ लोग होते हैं जो इन फ़र्क़ों को नज़रअंदाज़ करके ORM को पूरी तरह अच्छा या बुरा घोषित कर देते हैं
ऐसी बातों को attention खींचने वाली बहस समझकर छोड़ देना बेहतर है, और मैं उन चर्चाओं पर ध्यान देना चाहूँगा जो इस समझ से शुरू हों कि “ORM के फ़ायदे हैं, लेकिन यह कहाँ तक उपयोगी है यह समझना होगा, और उपयोग की दिक्कतें उसके फ़ायदों से ज़्यादा न होने पाएँ”
अगर data चाहिए, तो data access layer में जाओ, और अगर वह ज़रूरी चीज़ नहीं देती, तो pattern के हिसाब से नया repository या provider वगैरह बनाओ
चाहे ORM हो या खुद बनाया हुआ query composer, अगर app इतना “काफ़ी जटिल” लगने लगे कि यह ज़रूरी प्रतीत हो, तो वह पहले से ही स्थिर रूप से चलाने के लिए ज़रूरत से ज़्यादा जटिल हो चुका है
आख़िरकार या तो builder का मूल्यांकन ग़लत layer पर होने लगता है, या results पर iterate करते हुए यह दिखना बंद हो जाता है कि आप N+1 queries बना रहे हैं
ORM की ज़रूरत नहीं है
LINQ ठीक-ठीक ORM नहीं है; strongly typed LINQ statements expression trees में बदल जाते हैं, और फिर query provider उन्हें query में convert करता है
development के दौरान मैं model के भीतर ORM की readability को पसंद करता हूँ, लेकिन ज़रूरत पड़ने पर N+1 और दूसरी inefficiencies पर कड़ी नज़र रखकर optimize करता हूँ
“ज़रूरत पड़ने” की सीमा साफ़ नहीं होती, लेकिन मैं बहुत जल्दी optimization शुरू नहीं करना चाहता
नए project मैं अक्सर database से शुरू करता हूँ, और coding से पहले factories, seeders, और raw SQL queries के ज़रिए data model की समझ बनाता हूँ
Laravel का Eloquent जैसा ORM N+1 को संभालने और lazy loading करने के अच्छे methods देता है, लेकिन trade-off हमेशा रहते हैं
lazily composed queries की अनुमति देने वाली library के बजाय, आप query सीधे लिखते हैं और library compile time पर उसी query के लिए code generate करती है
जैसे
getUser: SELECT * FROM users WHERE id = ?जैसी query लिखने पर वहGetUserQueryclass औरgetUser(id: String): GetUserQueryResultजैसा method बना दे; मुझे यह model काफ़ी बेहतर लगता हैORM से मुझे मुख्य आपत्ति इस बात से है कि यह आधुनिक SQL engines को बढ़ा-चढ़ाकर पेश किए गए बेवकूफ़ bit storage की तरह treat करने की प्रवृत्ति रखता है
CTE, LATERAL joins, RETURNING clauses जैसी चीज़ें processing को बहुत सरल बना सकती हैं या data inconsistency की संभावना ख़त्म कर सकती हैं, लेकिन ORM आम तौर पर base tables और views को पहले से तय objects से साधारण mapping तक सीमित रहता है
अगर ORM tables भी बनाने लगे, तो हालात और बुरे हो जाते हैं
SQL अपनी प्रकृति में data extraction tool होने के साथ-साथ एक transformation language भी है, लेकिन ORM इस पहलू को लगभग नज़रअंदाज़ कर देता है, इसलिए बहुत से developers को यह तक नहीं पता चलता कि SQL में INSERT/SELECT/UPDATE/DELETE के अलावा भी बहुत कुछ है
pivot tables, temporal queries, CUBE/ROLLUP, window functions, set-returning functions, materialized views, external tables, JSON handling, date handling, exclusion constraints, ranges·intervals·domains जैसे types, row-level security, MERGE आदि भी हैं
जैसे आपके पास पूरा tool warehouse हो, लेकिन कोई आपको बस एक hammer, एक screwdriver और एक hacksaw पकड़ा दे और समझाए कि इतना ही काफ़ी है, और आप पूरा career यह जाने बिना गुज़ार दें कि कुछ मीटर दूर table saw, router, sander और wedges का पूरा set भी रखा है
ORM आम तौर पर आपको simple CRUD statements के इर्द-गिर्द सोचने पर मजबूर करता है, लेकिन शायद वही बेहतर है और advanced features का इस्तेमाल संयम से होना चाहिए
फिर भी जब DB इस्तेमाल करना पड़े, तो मैं जान-बूझकर DB features के बहुत छोटे subset तक ही सीमित रहने की कोशिश करता हूँ
क्योंकि “code” मेरे नियंत्रण का क्षेत्र है, जबकि “database” मुझे ऐसा जोखिमभरा और मुश्किल से पहुँच में आने वाला क्षेत्र लगता है जहाँ ग़लतियाँ बाद में, जैसे धीमे integration tests में, सामने आती हैं
DB के भीतर चलने वाला logic low-level tests की सीमा से बाहर होता है, इसलिए डरावना लगता है, और शायद मैं
select-from-selectquery तक इस्तेमाल न करूँtool warehouse का ज़्यादातर हिस्सा मैं ख़ुशी से छोड़े रहूँगा
basic data integrity protections को फिर से invent करने में ज़्यादातर समय बेहद जटिल workaround बनाने में चला जाता है
अपना ख़ुद का database बनाना सीखने के लिए मज़ेदार हो सकता है, लेकिन production apps में नहीं
ActiveRecord मुझे हमेशा अच्छा लगा है
कुछ exceptional cases ज़रूर होते हैं, लेकिन यह 80/20 point काफ़ी अच्छी तरह hit करता है, ज़रूरत पड़ने पर SQL में escape hatch देता है, और domain logic को व्यवस्थित करने वाले lifecycle hooks भी बढ़िया हैं और समझने में आसान भी
ऐसे practical ORM अच्छे लगते हैं जो सब कुछ किसी “bundle” के पीछे नहीं छिपाते और अपनी अलग query language नहीं थोपते
वे ORM जो ORM की समस्या को पूरी तरह “solve” करने की कोशिश करते हैं, उन्हें संभालना ज़्यादा कठिन होता है
ORM ऐसा ही होना चाहिए
लेकिन इसे सही तरह इस्तेमाल करने के लिए SQL की अच्छी पूर्व-समझ ज़रूरी है
समस्या तब पैदा होती है जब लोग SQL सीखे बिना AR द्वारा बनाई जाने वाली queries और उसकी सीमाओं को समझे बिना काम करते हैं
आधारभूत मान्यता ही गलत है। ORM कभी भी “हानिकारक आइडिया” नहीं रहा।
कुछ ORM के साथ काम करना बेहद खराब हो सकता है, लेकिन इसका मतलब यह नहीं कि पूरी श्रेणी ही बुरी सोच है।
मैं SQLAlchemy को कई सालों से खुशी-खुशी इस्तेमाल कर रहा हूँ क्योंकि यह SQL की अवधारणा को फिर से गढ़ने की कोशिश नहीं करता।
इसके बजाय यह query बनाने और आगे पास करने के लिए एक सुविधाजनक layer देता है, और छोटे-मोटे details को ठीक से संभालता है ताकि उन्हें हाथ से न करना पड़े।
हाल में Rust सीखते हुए साधारण CRUD के लिए boilerplate code खुद लिखना तकलीफ़देह और समय की बर्बादी लगा।
SQLAlchemy ORM ज़्यादा जटिल या optimize की जाने वाली queries में थोड़ा रास्ता रोक सकता है, लेकिन ऐसे मामलों में आप कभी भी सीधे SQL पर उतर सकते हैं।
हर चीज़ की तरह, कुछ स्थितियाँ ऐसी होती हैं जहाँ यह अच्छा फिट बैठता है और कुछ जहाँ नहीं, और किसी भी तकनीक का आसानी से overuse या misuse हो सकता है।
उदाहरण के लिए .NET का Entity Framework जैसा ORM, खासकर database-first तरीके से काम करते समय, बहुत बड़ी संपत्ति साबित हो सकता है।
अगर आपके पास सैकड़ों tables और सही foreign key relationships वाला DB है, तो ORM जटिल schema को समझने और बदलावों पर compile-time checks देने में मदद करता है।
embedded SQL एक दोधारी तलवार है जो performance फ़ायदे जैसी लग सकती है, लेकिन खासकर joins में hardcoded और verbose SQL को maintain करना बहुत मुश्किल होता है।
बात 5–10 tables की नहीं, सैकड़ों tables की है।
मैं किसी को मनाने की कोशिश नहीं कर रहा, लेकिन इंटरनेट पर best practices के बारे में जो पढ़ा है उसे ज्यों का त्यों मान लेना ठीक नहीं।
लोग अक्सर पूरी तरह अलग चीज़ों की बात कर रहे होते हैं, और चाहे कोई भी तकनीक हो, खराब developers हर जगह मिलेंगे।
अगर आप ORM या कोई और DB interface इस्तेमाल नहीं करते, तो CRUD जैसी चीज़ों के लिए अंततः आपको खुद एक बनानी और maintain करनी पड़ेगी।
और उसके भीतर अजीब bugs, edge cases और security holes आने की संभावना बहुत ज़्यादा होती है।
यह भी समस्या है कि SOLID जैसी बातों को विश्वविद्यालयों में software design principles के रूप में पढ़ाया जाता है।
अकादमिक दुनिया में समय, maintainability, पैसा और effort जैसी सीमाएँ कम मायने रखती हैं, इसलिए वहाँ यह ठीक लग सकता है, लेकिन नए graduates जब उद्योग में आते हैं तो ज़बरदस्त टकराव होता है।
क्योंकि वे पूरे दिन “परफ़ेक्ट” समाधान ढूँढते हुए yak shaving करने और wheel reinvent करने के आदी हो चुके होते हैं।
अगर उन्हें रोकने के लिए पर्याप्त और सक्षम senior/lead developers न हों, तो नतीजे में बहुत “दिलचस्प” products, budget overruns, बड़े हादसे, या इनका कोई मिश्रण मिलता है।
इससे भी बुरा तब होता है जब अकादमिक दुनिया में बनी और उसी के लिए डिज़ाइन की गई चीज़ें आम लोगों तक पहुँचा दी जाती हैं।
इसका एक अच्छा/बुरा उदाहरण OpenStack है, जिसमें CERN और सैकड़ों universities जैसे खास माहौल को support करने लायक knobs, levers और बेहिसाब modular components हैं, लेकिन यह इतना Byzantine है कि शुरुआत करना लगभग नामुमकिन हो जाता है।
ORM database को बिना मेहनत बदले जाने लायक नहीं बना देता, न ही यह generated SQL को सीखने और समझने की ज़रूरत खत्म करता है, और न ही schema को अपने-आप smooth बना देता है।
फिर भी लोग इसे इसलिए इस्तेमाल करते हैं क्योंकि यह एक standard abstraction है जिसे वरना आपको खुद दोहराना पड़ता।
यह DB access caching को संभव बनाता है, जो manual SQL के साथ scale बढ़ने पर हैरान कर देने वाली हद तक कठिन हो जाता है।
इसके साथ standardized tools और best practices मिलते हैं, जो N+1 जैसी समस्याओं को अप्रासंगिक बना सकते हैं।
ORM की मुख्य समस्या गलत उम्मीदें और खराब ORM हैं।
अगर आप ORM की कीमत समझना चाहते हैं, तो बिना ORM लिखे गए किसी project को खोलिए और उसमें कुछ भी बदलकर देखिए।
https://news.ycombinator.com/item?id=36498583 देखें।
न तो कोई उपयोगी काम आगे बढ़ा, या फिर चीज़ें तेज़ और गंदे तरीके की तुलना में 20–100 गुना ज़्यादा समय लेती रहीं।
सबसे बुरा मामला वह था जहाँ कुशल HTML designers की एक team को functional programming सीखने के लिए मजबूर किया गया।
backend configuration wizard आधुनिक engineering और elegant design का चमत्कार था, लेकिन उसे बनाने में 10 लोगों का 1 साल लग गया।
VC का पैसा लोगों को अजीब बना देता है।
SQL भाषा बहुत जटिल है, और एक सही मायनों में पूरा-featured query builder बनाना बिल्कुल भी मामूली काम नहीं है।
असली relational mapping वाले हिस्से को अलग रखकर भी यह बात सच है।
मेरा मानना है कि SQL उन मामलों में से है जहाँ “बस उस कमबख्त चीज़ को सीधे खुद प्रोग्राम करो” सही बात है
SQL या ORM लाइब्रेरी सीखने का ज़्यादा मतलब नहीं है, SQL को सीधे सीखना और इस्तेमाल करना बेहतर है
डेटाबेस एक्सेस शायद पूरे करियर में बार-बार आने वाला एक बुनियादी काम है, इसलिए असली तकनीक को सीधे सीखना सबसे अच्छा है
CSS भी कुछ ऐसा ही है; CSS लाइब्रेरी सीखने से बेहतर है CSS को सीखना और इस्तेमाल करना
सच कहूँ तो फ्रंटएंड डेवलपमेंट के लगभग हर पहलू में यही बात लागू होती है, और “form library” की जगह ब्राउज़र के form API को सीधे हैंडल किया जा सकता है
व्यक्तिगत रूप से मुझे SQL किसी भी ORM से कहीं ज़्यादा आसान लगा
गलत चीज़ सीखने की लागत पर समय बर्बाद नहीं करना चाहिए
CSS में भी यही बात है; CSS जानने पर सुविधा के लिए लाइब्रेरी चुनते समय कहीं ज़्यादा लचीलापन और समझ मिलती है
mainframe, desktop, client/server, web जैसे कई डेवलपमेंट प्लेटफॉर्म और उनके ऊपर की अनेक भाषाओं के दौर से गुज़रने के बाद भी SQL हमेशा एक साझा धागा रहा है
मैं पूरी तरह सहमत हूँ कि जो डेवलपर data layer और उसके नीचे क्या हो रहा है, उसे अच्छी तरह समझता है, वह ज़्यादा मज़बूत डेवलपर होता है
ORM की खासियतें सीखने में समय लगाने के बजाय वही समय SQL सीखने में क्यों न लगाया जाए — यह एक पुराना लेकिन सही सवाल है
SQL अनुभव का चक्रवृद्धि लाभ 10~15 साल बाद किसी खास प्लेटफॉर्म या भाषा के ORM से ज़्यादा मूल्यवान होने की अच्छी संभावना है
ORM सीखने और इस्तेमाल करने के कारण हो सकते हैं, लेकिन सिर्फ SQL सीखना नहीं चाहते इसलिए ORM की तरफ झुकना ठीक नहीं है
तभी पता चलता है कि उस abstraction की कीमत क्या चुकानी पड़ रही है। हाँ, अगर “zero-cost abstraction” हो तो बात अलग है
लेकिन अब Go types के साथ marshalling/unmarshalling की वजह से
azerकाcrudइस्तेमाल कर रहा हूँ, जिसे ORM की श्रेणी में रखा जा सकता हैGo standard library
sqlइतनी बुनियादी है कि object marshalling/unmarshalling लगभग खुद ही लिखनी पड़ती है, और वह बेहद उबाऊ हैआजकल अगर ORM इस्तेमाल करूँ, तो शायद सिर्फ उसी काम के लिए करूँगा
मुझे Dapper या Diesel जैसे “बीच के रास्ते” वाले micro ORM पसंद हैं
query SQL में लिखो, लेकिन strong typing और result set की object auto-mapping मिल जाती है
यानी productivity भी मिलती है और पूरी क्षमता वाली “असली” query language भी
मुझे यह तरीका भी पसंद आने लगा है कि object mapper को सिर्फ read-only query के लिए इस्तेमाल किया जाए
updates command pattern, यानी stored procedures से किए जाएँ, और उन्हें native methods जैसा दिखने के लिए map किया जा सकता है
डेवलपर्स को यह दिखावा बंद करना चाहिए कि SQL है ही नहीं, और बस इसे स्वीकार कर लेना चाहिए
Eloquent इस तरह के झंझट को इतना abstract कर देता है कि आप logic पर ध्यान दे सकें
मैं सिर्फ arrays और queries वाले एक “पुराने” PHP app को models और Eloquent वाली संरचना में फिर से लिख रहा हूँ, और यह पूरी तरह game changer लग रहा है
पहले .NET में SQLite इस्तेमाल करते समय मैंने भी इसी दिशा की एक wrapper library बनाई थी: https://github.com/zmj/sqlite-fast
यह थ्रेड ORM के mindshare dominance को अच्छी तरह दिखाता है
लगभग हर टिप्पणी में ORM का implicit alternative app code के अंदर string literals में लिखा raw SQL माना गया है
6 साल पहले से ही ऐसे tools मौजूद थे जो SQL को एक भाषा की तरह इस्तेमाल करते थे और ऐसे wrappers generate करते थे जो app में queries को methods के रूप में expose करते थे
जैसे queryfirst, pgtyped, pugsql, sqlc
यह एक paradigm shift था, या कम से कम हो सकता था, और यह साफ़ तौर पर काम करने का बेहतर तरीका दिखता है, लेकिन ORM और यह कभी न खत्म होने वाली बहस सारी ऑक्सीजन खींच लेती है, इसलिए यह चीज़ें हाशिये पर रह जाती हैं
SQL एक भाषा है, और वह भी बहुत high-level language
SQL को किसी और low-level language से जोड़ने की कोशिश करना “हाथ में हथौड़ा हो तो हर समस्या कील लगती है” वाली सोच का क्लासिक उदाहरण है
मान लो आप low-level assembly में कोड लिख रहे हों और किसी बड़े सिस्टम के साथ इंटरैक्ट कर रहे हों, लेकिन उस सिस्टम के docs कहें कि input सिर्फ JavaScript में ही व्यक्त किया जा सकता है, तब आपके पास विकल्प होते हैं
आप कोई अजीब-सी लाइब्रेरी ला सकते हैं जो pure assembly से कुछ जोड़-तोड़ करने दे ताकि
xxx.jsफाइल repository में commit न करनी पड़े, या फिर बस.jsफाइल में high-level language की ताकत का इस्तेमाल करके बात को व्यक्त कर सकते हैंइस्तेमाल हो रही SQL queries के लिए एक single source of truth मिल जाता है, और चूँकि असल में वही queries लिखी और maintain की जाती हैं, इसलिए नया index बनाने जैसी optimization भी आसान हो जाती है
raw SQL strings के ऊपर abstraction रखना बहुत उपयोगी है, लेकिन relations को objects होने का नाटक कराना चीज़ों को उलझाने वाला तरीका है
शायद TopLink भी करता था
stored procedures और local entities के बीच mapping इसी तरह संभाली जाती थी