.join.filter.like.order_by etc.. is crazy imo. It's often more complicated than that and doing it in a non-sql way is suboptimal/unmaintainable.
.join.filter.like.order_by etc.. is crazy imo. It's often more complicated than that and doing it in a non-sql way is suboptimal/unmaintainable.
It's also more composable, if you ask me. I like to think of it like "building" SQL statements using smaller components. Just like you do with code, you essentially compose a complicated business process using smaller blocks.
It's beautiful in it's simplicity. Even if the syntax requires some extra work/learning.
I've created a bunch of base queries that map from my user account table to each different table that users have access too. I can then use these base queries as a starting point to make sure people don't access records that don't belong to them.
bq = db.query(Obj).join(ParentA).join(ParentB).join(User).filter(User.id==bindparam('user_id'))
q = bq.filter(other_rules).params(user_id=1)...
It's a really flexible system.subqueries are best expressed in sql directly. They can get complicated, especially when using the with clause.
I am not saying that all of what ORM offers is bad. But beside the very basics they should step away. The less they offer the better.
# a subquery
demo_accounts = db.query(Account.id).join(Client).filter(Client.name=='Demo')
# used inside a query
print(db.query(Account.name).filter(Account.id.in_(demo_accounts)))
SELECT account.name AS account_name
FROM account
WHERE account.id IN (SELECT account.id AS account_id
FROM account JOIN client ON client.id = account.client_id
WHERE client.name = :name_1)
# or as a cte
da_as_cte = demo_accounts.cte()
print(db.query(Account.name).join(da_as_cte, da_as_cte.c.id==Account.id))
WITH anon_1 AS
(SELECT account.id AS id
FROM account JOIN client ON client.id = account.client_id
WHERE client.name = :name_1)
SELECT account.name AS account_name
FROM account JOIN anon_1 ON anon_1.id = account.id
There are obviously much more complex cases, but SA tends to handle things in a pretty sane way. You can compose query segments (like above) and if you really need to go back to the raw sql, you can and still have the results mapped into your python objects.Also, you're neglecting all the other benefits you get. Things like the loading strategies and the unit of work tracking are extremely powerful abstractions.
Use ORM for: 1. INSERT, UPDATE, DETELE get one record
Use SQL/Stored Procedure for: SELECTs that involved more complex joins and queries.
However, in the select, where'd you'd have to join all three tables, you might use SQL, yes?
I'm just curious how people are using ORMs vs SQL, so sorry for the questions.
If you're using a different ORM then things are probably going to be different. I've worked with a few in various languages and SA is the only one I've found that allows me to express any complex query directly via the ORM. I've heard there are some edge cases where you need to drop down a layer but I haven't run into them yet.
Right now I am working with a suboptimal database design, where I need two nested subqueries to get the most recent event in a related row. I changed them to joins then to (indexed) temporary tables, to try and improve MySQl's performance. It worked to a degree. I doubt that would be possible in an ORM as it is working at the databse level rather than a hgher abstraction.
ORM's win hands down over multiple insert and update queries. Complex queries are usually better in SQL.