Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ndb
Search
spicyj
May 28, 2014
Technology
0
120
ndb
spicyj
May 28, 2014
Tweet
Share
More Decks by spicyj
See All by spicyj
React: What Lies Ahead
spicyj
6
360
Creating interactive learning interfaces at Khan Academy
spicyj
0
110
Understanding state in React
spicyj
1
99
css
spicyj
2
820
Other Decks in Technology
See All in Technology
「経験の点」の位置を意識したキャリア形成 / Career development with an awareness of the “point of experience” position
pauli
4
120
Winning at PHP in Production in 2025
beberlei
1
230
Goの組織でバックエンドTypeScriptを採用してどうだったか / How was adopting backend TypeScript in a Golang company
kaminashi
12
8.9k
地味にいろいろあった! 2025春のAmazon Bedrockアップデートおさらい
minorun365
PRO
2
520
更新系と状態
uhyo
8
2.1k
Web Intelligence and Visual Media Analytics
weblyzard
PRO
1
5.9k
もう難しくない!誰でもカンタンDocker入門 〜30分であなたのPCにアプリを立ち上げる〜
devops_vtj
0
130
AI 코딩 에이전트 더 똑똑하게 쓰기
nacyot
0
360
エンジニアリングで組織のアウトカムを最速で最大化する!
ham0215
1
260
営業向け誰でも話せるOCIセールストーク
oracle4engineer
PRO
2
130
グループ ポリシー再確認 (2)
murachiakira
0
170
白金鉱業Meetup_Vol.18_生成AIはデータサイエンティストを代替するのか?
brainpadpr
3
200
Featured
See All Featured
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.6k
The Power of CSS Pseudo Elements
geoffreycrofte
75
5.8k
Why You Should Never Use an ORM
jnunemaker
PRO
56
9.3k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.4k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
357
30k
Optimizing for Happiness
mojombo
378
70k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
14
1.4k
The Pragmatic Product Professional
lauravandoore
33
6.6k
Git: the NoSQL Database
bkeepers
PRO
430
65k
The Cost Of JavaScript in 2023
addyosmani
49
7.7k
Fireside Chat
paigeccino
37
3.4k
The Language of Interfaces
destraynor
157
25k
Transcript
ndb “NDB is a better datastore API for the Google
App Engine Python runtime.”
Part 1 of 2
Why ndb? 1. Less stupid by default 2. More flexible
queries 3. Tasklets with autobatching
Less stupid by default With db: class UserVideo(db.Model): user_id =
db.StringProperty() video = db.ReferenceProperty(Video) user_video = UserVideo.get_for_video_and_user_data( video, user_data) return jsonify(user_video) # slow
Less stupid by default With ndb: class UserVideo(ndb.Model): user_id =
ndb.StringProperty() video = ndb.KeyProperty(kind=Video) user_video = UserVideo.get_for_video_and_user_data( video, user_data) return jsonify(user_video) # not slow!
More flexible queries ndb lets you build filters using ndb.AND
and ndb.OR: questions = Feedback.query() .filter(Feedback.type == 'question') .filter(Feedback.target == video_key) .filter(ndb.OR( Feedback.is_visible_to_public == True, Feedback.author_user_id == current_id)) .fetch(1000) Magic happens.
Performance The datastore is slow. How can we speed things
up? 4 Batch operations together 4 Do things in parallel 4 Avoid the datastore
Tasklets and autobatching def get_user_exercise_cache(user_data): uec = UEC.get_for_user_data(user_data) if not
uec: user_exercises = UE.get_all(user_data) uec = UEC.build(user_exercises) return uec def get_all_uecs(user_datas): return map(get_user_exercise_cache, user_datas)
Tasklets and autobatching @ndb.tasklet def get_user_exercise_cache_async(user_data): uec = yield UEC.get_for_user_data_async(user_data)
if not uec: user_exercises = yield UE.get_all(user_data) uec = UEC.build(user_exercises) raise ndb.Return(uec) @ndb.synctasklet def get_all_uecs(user_datas): uecs = yield map(get_user_exercise_cache_async, user_datas) raise ndb.Return(uecs)
Moral ndb is awesome. Use it.
Part 2 of 2
The sad truth ndb isn't perfect.
Mysterious errors You heard from Marcia about this gem back
in March: TypeError: '_BaseValue' object is not subscriptable
Q: What's worse than code that doesn't work at all?
A: Code that mostly works but breaks in subtle ways.
Secret slowness #1 Multi-queries, with IN and OR: answers =
Feedback.query() .filter(Feedback.type == 'answer') .filter(Feedback.in_reply_to.IN(question_keys)) .fetch(1000) Doesn't run in parallel!
Secret slowness #1 A not-horribly-slow multi-query: answers = Feedback.query() .filter(Feedback.type
== 'answer') .filter(Feedback.in_reply_to.IN(question_keys)) .order(Feedback.__key__) .fetch(1000)
Secret slowness #2 Query iterators: query = Feedback.query().filter( Feedback.topic_ids ==
'algebra') questions = [] for q in query.iter(batch_size=20): if q.is_visible_to(user_data): questions.append(q) if len(questions) >= 10: break
Secret slowness #2 Solution? Sometimes you have to do it
by hand.
Moral ndb isn't perfect. Pay attention. Profile your code.
The End