from days to minutes, from - europython 2019€¦ · todo: add slides showing code examples...
TRANSCRIPT
![Page 1: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/1.jpg)
![Page 2: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/2.jpg)
From days to minutes, fromFrom days to minutes, fromminutes to milliseconds withminutes to milliseconds with
SQLAlchemySQLAlchemyLeonardo Rochael Almeida
10-July-2019
![Page 3: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/3.jpg)
Hi, I’m Leo. I’m a Tech Lead at Geru.
I’m here today to talk to you about ORMs and performance.
I’m by no means an expert in either SQL, SQLAlchemy or ORMs.
But I’d like to pass on lessons learned while optimizing some processes in my company.
Speaker notes
![Page 4: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/4.jpg)
GeruGeruBrazillian FintechBrazillian Fintech
Backend Stack:
Others (Celery, MongoDB, Java, …)
![Page 5: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/5.jpg)
Our backend stack is almost all Python, with storage mostly in PostgreSQL through SQLAlchemy.
Speaker notes
![Page 6: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/6.jpg)
SQLAlchemySQLAlchemyTwo aspects:
SQL Expression Language (a Python DSL)
X
Object Rela�onal Mapper (ORM)
![Page 7: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/7.jpg)
SQLAlchemy has two aspects:
The SQL Expression Langage, which is a way of mapping SQL constructs into a Pythonic Domain SpecificLanguage (DSL)The Object Relational Mapper, which allows mapping Python classes to tables and records of those tables toinstances of the respective classes.
The ORM is built upon the DSL, but they can be used without one another.
At Geru we use the ORM almost exclusively.
TODO: Add slides showing code examples contrasting DSL/ORM
Speaker notes
![Page 8: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/8.jpg)
SQLAlchemy is Awesome!SQLAlchemy is Awesome!However:
Frameworks s�ll require you to makedecisions about how to use them, and
knowing the underlying pa�erns isessen�al if you are to make wise choices.
- Mar�n Fowler
h�ps://mar�nfowler.com/books/eaa.html
![Page 9: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/9.jpg)
The ORM TrapThe ORM Trap
![Page 10: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/10.jpg)
The ORM TrapThe ORM TrapSensible Python code ➡ Bad SQL access pa�erns
![Page 11: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/11.jpg)
The ORM TrapThe ORM TrapSensible Python code ➡ Bad SQL access pa�ernsUnno�ceable at low data volumes
![Page 12: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/12.jpg)
The ORM TrapThe ORM TrapSensible Python code ➡ Bad SQL access pa�ernsUnno�ceable at low data volumesLike… during development…
![Page 13: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/13.jpg)
The ORM TrapThe ORM TrapSensible Python code ➡ Bad SQL access pa�ernsUnno�ceable at low data volumesLike… during development…And early produc�on…
![Page 14: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/14.jpg)
Using a good ORM feels great. Most of the time you forget it’s even there!
And that is actually the problem, because the DB is an external system with an API and should be treated as such.
The API just happens to be SQL…
Speaker notes
![Page 15: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/15.jpg)
The Fix: Let the DB do its JobThe Fix: Let the DB do its Job
![Page 16: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/16.jpg)
The Fix: Let the DB do its JobThe Fix: Let the DB do its JobBe aware of implicit queries.
![Page 17: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/17.jpg)
The Fix: Let the DB do its JobThe Fix: Let the DB do its JobBe aware of implicit queries.
Specially from rela�onships.
![Page 18: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/18.jpg)
The Fix: Let the DB do its JobThe Fix: Let the DB do its JobBe aware of implicit queries.
Specially from rela�onships.
Aim for O(1) queries per request/job/ac�vity.
![Page 19: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/19.jpg)
The Fix: Let the DB do its JobThe Fix: Let the DB do its JobBe aware of implicit queries.
Specially from rela�onships.
Aim for O(1) queries per request/job/ac�vity.
Avoid looping through model instances
![Page 20: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/20.jpg)
The Fix: Let the DB do its JobThe Fix: Let the DB do its JobBe aware of implicit queries.
Specially from rela�onships.
Aim for O(1) queries per request/job/ac�vity.
Avoid looping through model instances
Let the DB do it for you
![Page 21: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/21.jpg)
Be mindful of the work that the database is doingSpecially the amount of DB round-tripsBut also the amount of data traffic (row count)
Speaker notes
![Page 22: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/22.jpg)
Geru Case 1: The 24+ hourGeru Case 1: The 24+ hourreportsreports
Now it takes minutes
![Page 23: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/23.jpg)
Geru Funding ModelGeru Funding Model
![Page 24: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/24.jpg)
Geru is a Fintech that lends money at rates much lower than the mainstream banks in Brazil. We work online exclusively.
During each month, borrowers pay their monthly instalments, and at the beginning of every month Geru pays back theDebenture Holders.
This is very simplified of course, there are lots of details on top of that:
Debentures bought later “cost” more but are “worth” the same
Debenture remuneration is complicated by tax details like
Amortization paid back doesn’t pay taxes but the premium on top does payAmount of time invested reduce taxes
Different series have different payback rules
Speaker notes
![Page 25: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/25.jpg)
Entities and RelationshipsEntities and Relationships
![Page 26: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/26.jpg)
ORM DeclarationORM DeclarationDBSession = scoped_session(sessionmaker(...))
class ORMClass(object):"""Base class for all models"""@classpropertydef query(cls):
""" Convenient query for records of a model, like:
query = MyModel.query.filter(...).order_by(...) """
return DBSession.query(cls)
Base = declarative_base(cls=ORMClass)
![Page 27: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/27.jpg)
Model DeclarationModel Declarationclass Debenture(Base):
id = Column(Integer, primary_key=True) series_number = Column(Integer, nullable=False)
sale_price = Column(Numeric, nullable=True)
sale_date = Column(Date, nullable=True)
# cont ...
![Page 28: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/28.jpg)
Model DeclarationModel Declarationclass Debenture(Base):
# cont ... holder_id = Column( Integer, ForeignKey('debenture_holder.id'), nullable=True, index=True, ) holder = relationship(
'DebentureHolder', backref=backref('debentures', lazy='dynamic',
), foreign_keys=[holder_id], )
# cont ...
![Page 29: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/29.jpg)
Model DeclarationModel Declarationclass Debenture(Base):
# cont ... series_id = Column( Integer, ForeignKey('debenture_series.id'), nullable=False, index=True, )
series = relationship('DebentureSeries', backref=backref(
'debentures', lazy='dynamic', ), foreign_keys=[series_id], )
![Page 30: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/30.jpg)
First things �rst: loggingFirst things �rst: logging# development.ini[loggers]keys = sqlalchemy
[logger_sqlalchemy]qualname = sqlalchemy.enginelevel = INFO# "level = INFO" logs SQL queries.# "level = DEBUG" logs SQL queries and results.# "level = WARN" logs neither (in production).
![Page 31: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/31.jpg)
So I had to debug an issue in the distribution code, but it was taking way too long at each run.
So the first thing I did was to enable sqlalchemy statement logging in my development instance, and what I saw wasgobs of repeated statements, all alike, just rolling through the logs.
Speaker notes
![Page 32: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/32.jpg)
Understanding the cacheUnderstanding the cacheoptimizationoptimization
See diff and Jupyter
![Page 33: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/33.jpg)
It’s perfectly reasonable in pure Python to sum() over an iteration of attribute accessess in generator comprehension.
But if the generator comprehension is looping over a query then a lot of data is being fetched from the database so thatin the end the Python programmer could calculate do what the database could reply with a single line of SQL.
Speaker notes
![Page 34: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/34.jpg)
Understanding theUnderstanding theinsert/update optimizationinsert/update optimization
See diff and Jupyter
![Page 35: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/35.jpg)
When the optimizationWhen the optimizationback�resback�res
See diff and Jupyter
![Page 36: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/36.jpg)
Unfortunately at some point the complex query that allowed to fetch all information of each integralization started takinghours.
It was a single query taking many hours to execute.
Fortunately it was easy to locate as it was a single query envelopped by logging calls.
The query was then broken into two parts, the second of which was executed in a loop for each integralization. Since theamount of data transmitted was small, and only a single query per loop was added inside a loop that already containedmultiple other slower queries, it had no negative impact, and the outer query ran again at the same 2 minutes timeframeas in the beginning.
Speaker notes
![Page 37: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/37.jpg)
Geru Case 2: The 1+minuteGeru Case 2: The 1+minutepagepage
Now renders in less than a second.
![Page 38: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/38.jpg)
First things �rst: slowlogFirst things �rst: slowlog[app:main]pyramid.includes = pyramid_tm
[...] slowlog
# Slowlog configuration:slowlog = trueslowlog_file = logs/slow.log
![Page 39: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/39.jpg)
A complete understanding of what slowlog does is out of scope for this talk (there is talk by me at PyConUS 2013 aboutit on YouTube), but basically slowlog watches for wsgi requests that take too long and starts dumping periodic stacktraces of the thread handling the slow requests.
Makes it ease to see which point of the code is responsible for the performance issues.
Speaker notes
![Page 40: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/40.jpg)
Understanding theUnderstanding theauthorization optimizationauthorization optimization
See diff
![Page 41: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/41.jpg)
ConclusionsConclusionsUnderstand SQLUnderstand SQL
![Page 42: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/42.jpg)
ConclusionsConclusionsUnderstand SQLUnderstand SQL
SELECT Documenta�on
![Page 43: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/43.jpg)
ConclusionsConclusionsUnderstand SQLUnderstand SQL
SELECT Documenta�onGROUP BY vs aggrega�on func�ons
![Page 44: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/44.jpg)
ConclusionsConclusionsUnderstand SQLUnderstand SQL
SELECT Documenta�onGROUP BY vs aggrega�on func�onsaggrega�on func�on w/ filters
![Page 45: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/45.jpg)
ConclusionsConclusionsUnderstand SQLUnderstand SQL
SELECT Documenta�onGROUP BY vs aggrega�on func�onsaggrega�on func�on w/ filtersDISTINCT ON
![Page 46: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/46.jpg)
ConclusionsConclusionsUnderstand SQLUnderstand SQL
SELECT Documenta�onGROUP BY vs aggrega�on func�onsaggrega�on func�on w/ filtersDISTINCT ONwindow expressions
![Page 47: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/47.jpg)
Study SQL:
Read the SELECT documentation of your database. Understand how aggregation functions (sum(),array_agg()) interfere with the cardinality (number of rows) of the result and how they interact with GROUP BY.
Understand DISTINCT and specially DISTINCT ONUnderstand "window" expressions
sum(X) OVER (PARTITION BY ... ORDER BY)
Read about CTEs (WITH statement) and subqueries, and how/where you can use them.Understand how to insert and update rows that match the result of other queries.
Speaker notes
![Page 48: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/48.jpg)
ConclusionsConclusionsTHEN Study SQLAlchemyTHEN Study SQLAlchemy
![Page 49: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/49.jpg)
ConclusionsConclusionsTHEN Study SQLAlchemyTHEN Study SQLAlchemy
Be aware of the underlying queries
![Page 50: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/50.jpg)
ConclusionsConclusionsTHEN Study SQLAlchemyTHEN Study SQLAlchemy
Be aware of the underlying queries
Push work to the DB
![Page 51: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/51.jpg)
ConclusionsConclusionsTHEN Study SQLAlchemyTHEN Study SQLAlchemy
Be aware of the underlying queries
Push work to the DB
As much as possible
![Page 52: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/52.jpg)
ConclusionsConclusionsTHEN Study SQLAlchemyTHEN Study SQLAlchemy
Be aware of the underlying queries
Push work to the DB
As much as possible
But not too much
![Page 53: From days to minutes, from - EuroPython 2019€¦ · TODO: Add slides showing code examples contrasting DSL/ORM Speaker notes. SQLAlchemy is Awesome! However: Frameworks s ll require](https://reader033.vdocument.in/reader033/viewer/2022052012/6027b6c65d5362720951eea6/html5/thumbnails/53.jpg)
THEN Study SQLAlchemy
Learn how to produce in SQLAlchemy the same optimized access patterns you know are possible inSQL
Be aware of the underlying queries
All attribute accesses could represent a roundtrip. Atomic values usually don’t (though they can if youask SQLAlchemy to defer loading columns). But all relatioship attributes do, unless they’re not dynamicand have been previously accessed in the same session.
Speaker notes