[{"data":1,"prerenderedAt":371},["ShallowReactive",2],{"project-20041076":3},{"id":4,"name":5,"line":6,"line_source":7,"title":8,"url":9,"domain":10,"maker":11,"posted_at":12,"year":13,"points":14,"comments":15,"rank_in_year":16,"shown_in_year":17,"top":18,"tier":19,"category":20,"subcategory":21,"format":22,"keywords":23,"reception":29,"sentiment":30,"stance_mix":31,"scored_comments":36,"aspects":37,"strip":43,"post_text":46,"what":47,"said":91,"maker_in_thread":200,"shape":205,"grid":209,"attempts":333,"same_week":334,"maker_shows":45,"maker_hidden":363,"reader_version":364,"card":365},"20041076","PugSQL","A Python Port of HugSQL","title","Show HN: PugSQL, a Python Port of HugSQL","https:\u002F\u002Fpugsql.org","pugsql.org","mcfunley",1559142583,2019,155,53,262,2195,12,"notable","languages","database query library","library",[24,25,26,27,28],"python sql","hugsql","sql queries","sqlalchemy","yesql","debated",0.182,{"positive":32,"neutral":33,"mixed":34,"critical":35},10,3,0,7,20,{"idea":38,"design":41},{"positive":39,"critical":40},8,4,{"positive":34,"critical":42},2,[44,34,34,34,34,34,44,34,34,34,44,34,45,33,34,34,44,45,44,44,34,34,34,44,33,45,34,45,34,45,44,34,34,34,34,34,33,33,34,34],5,1,null,{"problem":48,"audience":64,"pricing":46,"motivation":46,"time_to_build":46,"stack":72,"openness":90,"stage":90,"team_size":90},{"value":49,"source":50,"evidence":51},"Organising raw SQL queries in separate files and calling them from Python.","inferred",[52,56,60],{"id":53,"by":54,"text":55},"20043359","phaer","I haven't used PugSQL yet, but I like the principle because it allows to keep SQL and Python code in separate files, which makes it easier to use linters or even just proper…",{"id":57,"by":58,"text":59},"20044734","michelpp","You may of course already be aware of this but it's worth pointing out. To many, SQLAlchemy is an ORM, but the SA developers very purposefully made the ORM layer completely…",{"id":61,"by":62,"text":63},"20049590","fulafel","One clear advantage of the yesql\u002Fhugsql style is that you get to manage your SQL files in a consistent way. You're going to have migration files and stored procedure\u002Fview\u002Fetc…",{"value":65,"source":50,"evidence":66},"Python developers who prefer writing raw SQL.",[67,68],{"id":53,"by":54,"text":55},{"id":69,"by":70,"text":71},"20047368","BerislavLopac","I see this as a perfectly complementary tool to SQLAlchemy Core itself: you can write your queries in Core, reusing as much as necessary -- but there is always a couple of…",[73,78],{"value":74,"source":50,"evidence":75},"Python",[76],{"id":77},"post",{"value":79,"source":80,"evidence":81},"SQLAlchemy","commenter",[82,86],{"id":83,"by":84,"text":85},"20043040","Scarbutt","Looks like sqlalchemy is just used for the \"being able to handle multiple databases\" part, not for its higher level abstractions.",{"id":87,"by":88,"text":89},"20043005","born2discover","Interesting. But what a potential use case for this? I mean what makes it stand out when put side by side with SQLAlchemy? Does it do anything differently? From what I've been…","unknown",{"praise":92,"objections":113,"requests":144,"questions":156,"alternatives":169},[93,98],{"value":94,"source":80,"evidence":95},"Keeping SQL in separate files aids linting, syntax highlighting and consistent query management.",[96,97],{"id":53,"by":54,"text":55},{"id":61,"by":62,"text":63},{"value":99,"source":80,"evidence":100},"Clean, simple approach that bridges raw SQL and query builders.",[101,105,109],{"id":102,"by":103,"text":104},"20044543","avolcano","I really like the idea of this! Potentially quite helpful for the GraphQL space, I think, since these query files could map 1:1 with resolvers (if I understand GraphQL…",{"id":106,"by":107,"text":108},"20044954","holtalanm","i really really want to work on porting HugSQL to Elixir. debating starting on that for my next side project. i remember when learning clojure, HugSQL was one my of favorite…",{"id":110,"by":111,"text":112},"20044632","loop0","I started the same project with the same name a few months ago, I’m happy to see someone went farther than I did. Congrats on this project, I’m testing later. HugSQL achieves the…",[114,126,137],{"value":115,"source":80,"evidence":116},"Built on SQLAlchemy, so it seems an unnecessary wrapper over SQLAlchemy Core.",[117,118,122],{"id":87,"by":88,"text":89},{"id":119,"by":120,"text":121},"20042756","coleifer","A simple Python interface ... built atop the most powerful and widely used Python ORM. This is the library equivalent of virtualization! This is crazy, right? Let's take…",{"id":123,"by":124,"text":125},"20043419","sametmax","SQLAlchemy-core is not an ORM either, the ORM is based on it. You can already write raw sql with it in a separate file if needed, and make a function out of it. I can't see a…",{"value":127,"source":80,"evidence":128},"No easy way to compose or reuse query fragments for optional filters.",[129,133],{"id":130,"by":131,"text":132},"20044431","pbecotte","Imagine a query - `select * from users`. Now, in my webapp, the user can pass a username, in which case I want to do `select * from users where username=\u003Csome string>`. In naive…",{"id":134,"by":135,"text":136},"20045851","balfirevic","It's either two queries or something like this: select * from users where username = :username or :username is null That can be considered slightly better than two queries or…",{"value":138,"source":80,"evidence":139},"Name clashes with the Pug template engine on npm.",[140],{"id":141,"by":142,"text":143},"20041974","robodale","Watch your naming - pug is also a template engine for npm.",[145,149],{"value":146,"source":80,"evidence":147},"Ports of HugSQL to other languages such as Elixir.",[148],{"id":106,"by":107,"text":108},{"value":150,"source":80,"evidence":151},"Async database support.",[152],{"id":153,"by":154,"text":155},"20044212","benatkin","Perhaps slightly unrelated: I'm considering moving to asyncpg and using quart, which is a port of flask to async python. What I wonder if it's time to start using async python,…",[157,161],{"value":158,"source":80,"evidence":159},"What does it offer beyond SQLAlchemy?",[160],{"id":87,"by":88,"text":89},{"value":162,"source":80,"evidence":163},"Can query types be generated or validated statically?",[164,165],{"id":102,"by":103,"text":104},{"id":166,"by":167,"text":168},"20050795","Rotareti","> I've been writing runtime validations for each individual query result. This has been a bit annoying to maintain at scale since I don't have very good patterns for it. I think…",[170,175,179,186,193],{"value":171,"source":80,"evidence":172},"SQLAlchemy Core",[173,174],{"id":83,"by":84,"text":85},{"id":57,"by":58,"text":59},{"value":176,"source":80,"evidence":177},"Pydantic",[178],{"id":166,"by":167,"text":168},{"value":180,"source":80,"evidence":181},"Dataset",[182],{"id":183,"by":184,"text":185},"20043250","nrjames","Dataset is my favorite dumb wrapper on top of SQLAlchemy. https:\u002F\u002Fdataset.readthedocs.io\u002Fen\u002Flatest\u002F",{"value":187,"source":80,"evidence":188},"JDBI",[189],{"id":190,"by":191,"text":192},"20041934","buremba","The Java\u002FKotlin alternative would be `the amazing library` JDBI: http:\u002F\u002Fjdbi.org\u002F",{"value":194,"source":80,"evidence":195},"Ecto",[196],{"id":197,"by":198,"text":199},"20048091","arthurbrown","Ecto is one of the very best things about elixir from my perspective. It seems bizarre that anyone would have this great tool uniquely available to their language and want to…",{"comments":45,"answered":34,"key":201},[202],{"id":203,"text":204},"20042217","If you want to put sql in your templates, I can't help you",{"commenters":206,"max_depth":44,"maker_replies":45,"first_comment_mins":207,"lifespan_hours":208},43,60,28,[210,212,216,217,221,222,225,228,230,231,234,237,238,241,242,244,247,250,252,255,256,259,260,263,265,266,269,270,273,276,278,282,286,287,289,292,293,296,299,300,302,303,306,307,310,313,315,317,320,323,326,327,330],[102,34,44,211,103,34],"project\u002Fpositive\u002Fidea",[213,34,34,214,215,34],"20045921","commenter\u002Fneutral\u002Fnone","petetnt",[166,34,34,214,167,34],[218,45,34,219,220,34],"20043685","other\u002Fneutral\u002Fnone","cjauvin",[153,42,34,219,154,34],[223,42,34,219,224,34],"20044569","linsomniac",[226,42,34,219,227,34],"20047204","bpicolo",[229,42,34,219,70,34],"20047323",[106,33,44,211,107,34],[232,33,34,214,233,34],"20045411","kungfooguru",[235,33,34,236,107,34],"20045562","commenter\u002Fpositive\u002Fnone",[197,33,34,219,198,34],[239,33,34,240,107,34],"20053874","commenter\u002Fpositive\u002Fidea",[110,40,44,211,111,34],[243,44,34,219,62,34],"20043024",[245,44,34,219,246,34],"20044060","jjwiseman",[87,248,45,249,88,34],6,"project\u002Fcritical\u002Fidea",[83,248,33,251,84,34],"project\u002Fneutral\u002Fnone",[253,248,34,214,254,34],"20043573","eshyong",[57,248,34,214,58,34],[257,248,34,236,258,34],"20048610","Drdrdrq",[53,248,44,211,54,34],[261,248,45,262,124,34],"20043484","project\u002Fcritical\u002Fdesign",[264,248,34,214,54,34],"20044119",[61,248,44,211,62,34],[267,248,44,211,268,34],"20050509","nicwolff",[190,35,34,219,191,34],[271,35,34,219,272,34],"20044071","BossingAround",[274,35,34,219,275,34],"20045330","encloser",[277,35,34,214,272,34],"20048861",[279,39,44,280,281,34],"20042312","project\u002Fpositive\u002Fnone","gigatexal",[283,284,44,211,285,34],"20044399",9,"cwp",[119,32,45,249,120,34],[288,32,45,249,124,34],"20043130",[290,32,34,214,291,34],"20043136","nathell",[123,32,45,249,124,34],[294,32,34,219,295,34],"20054820","ptttr",[297,32,34,240,298,34],"20043151","ethanpil",[130,32,45,262,131,34],[134,32,33,301,135,34],"project\u002Fneutral\u002Fdesign",[69,32,44,211,70,34],[304,32,34,219,305,34],"20053628","infinite8s",[183,32,34,219,184,34],[308,32,34,236,309,34],"20044458","gtycomb",[311,32,34,219,312,34],"20046368","zzzeek",[314,32,34,219,120,34],"20046614",[316,32,34,219,305,34],"20053526",[141,318,45,319,142,34],11,"project\u002Fcritical\u002Fnone",[321,318,44,280,322,34],"20042106","lkschubert8",[324,318,33,251,325,34],"20042203","noir_lord",[203,318,34,219,11,45],[328,318,34,219,329,34],"20048932","benbristow",[331,318,34,219,332,34],"20043271","gmueckl",[],[335,340,345,349,354,358],{"id":336,"name":337,"points":338,"category":339},"20012687","nextdns.io",372,"infrastructure",{"id":341,"name":342,"points":343,"category":344},"20008466","tiptap",278,"dev_tools",{"id":346,"name":347,"points":348,"category":344},"20033728","Endoflife.date",248,{"id":350,"name":351,"points":352,"category":353},"20001339","Workstation",206,"consumer_social",{"id":355,"name":356,"points":357,"category":344},"20019877","youtube-dl-interactive",196,{"id":359,"name":360,"points":361,"category":362},"20024448","Imgsquash",178,"creative",false,"v2",{"id":366,"name":5,"line":6,"ai":363,"cat":20,"year":13,"points":14,"comments":15,"rec":29,"s":367,"top":18,"kw":368,"maker":11,"domain":10,"tier":19,"attempts":34,"strip":369,"url":9,"mix":370,"praise":94,"objection":115,"sub":21},20041076,0.18,[24,25,26,27,28],"5000005000501300515500053101015000003300",[32,33,34,35],1793990989969]