SlideShare una empresa de Scribd logo
1 de 23
Descargar para leer sin conexión
VALIDATED DOCUMENTS ON
MONGODB WITH MING
Alessandro Molina
@__amol__
amol@turbogears.org
Who am I
● CTO @ Axant.it, mostly Python company
(with some iOS and Android)
● TurboGears development team member
● Contributions to Ming project ODM layer
● Really happy to be here at PyConUK!
○ I thought I would have crashed my car driving on
the wrong side!
MongoDB Models
● Schema free
○ It looks like you don’t have a schema, but your
code depends on properties that need to be there.
● SubDocuments
○ You know that a blog post contain a list of
comments, but what it is a comment?
● Relations
○ You don’t have joins and foreign keys, but you still
need to express relationships
What’s Ming?
● MongoDB toolkit
○ Validation layer on pymongo
○ Manages schema migrations
○ In Memory MongoDB
○ ODM on top of all of those
● Born at sourceforge.net
● Supported by TurboGears
community
MongoDB
PyMongo
Ming
Ming.ODM
Getting Started with the ODM
● Ming.ODM looks like SQLAlchemy
● UnitOfWork
○ Avoid half-saved changes in case of crashes
○ Flush all your changes at once
● IdentityMap
○ Same DB objects are the same object in memory
● Supports Relations
● Supports events (after_insert, before_update, …)
Declaring Schema with the ODM
class WikiPage(MappedClass):
# Metadata for the collection
# like its name, indexes, session, ...
class __mongometa__:
session = DBSession
name = 'wiki_page'
unique_indexes = [('title',)]
_id = FieldProperty(schema.ObjectId)
title = FieldProperty(schema.String)
text = FieldProperty(schema.String)
# Ming automatically generates
# the relationship query
comments = RelationProperty('WikiComment')
class WikiComment(MappedClass):
class __mongometa__:
session = DBSession
name = 'wiki_comment'
_id = FieldProperty(schema.ObjectId)
text=FieldProperty(s.String, if_missing='')
# Provides an actual relation point
# between comments and pages
page_id = ForeignIdProperty('WikiPage')
● Declarative interface for models
● Supports polymorphic models
Querying the ODM
wp = WikiPage.query.get(title='FirstPage')
# Identity map prevents duplicates
wp2 = WikiPage.query.get(title='FirstPage')
assert wp is wp2
# manually fetching related comments
comments = WikiComment.query.find(dict(page_id=wp._id)).all()
# or
comments = wp.comments
# gets last 5 wikipages in natural order
wps = WikiPage.query.find().sort('$natural', DESCENDING).limit(5).all()
● Query language tries to be natural for both
SQLAlchemy and MongoDB users
The Unit Of Work
● Flush or Clear the pending changes
● Avoid mixing UOW and atomic operations
● UnitOfWork as a cache
wp = WikiPage(title='FirstPage', text='This is my first page')
DBSession.flush()
wp.title = "TITLE 2"
DBSession.update(WikiPage, {'_id':wp._id}, {'$set': {'title': "TITLE 3"}})
DBSession.flush() # wp.title will be TITLE 2, not TITLE 3
wp2 = DBSession.get(WikiPage, wp._id)
# wp2 lookup won’t query the database again
How Validation works
● Ming documents are validated at certain
points in their life cycle
○ When saving the document to the database
○ When loading it from the database.
○ Additionally, validation is performed when the
document is created through the ODM layer or
using the .make() method
■ Happens before they get saved for real
Cost of Validation
● MongoDB is famous for its speed, but
validation has a cost
○ MongoDB documents can contain many
subdocuments
○ Each subdocument must be validated by ming
○ Can even contain lists of multiple subdocuments
Cost of Validation benchmark
#With Validation
class User(MappedClass):
# ...
friends = FieldProperty([dict(fbuser=s.String,
photo=s.String,
name=s.String)], if_missing=[])
>>> timeit.timeit('User.query.find().all()', number=20000)
31.97218942642212
#Without Validation
class User(MappedClass):
# ...
friends = FieldProperty(s.Anything, if_missing=[])
>>> timeit.timeit('User.query.find().all()', number=20000)
23.391359090805054
#Avoiding the field at query time
>>> timeit.timeit('User.query.find({}, fields=("_id","name")).all()', number=20000)
21.58667516708374
Only query what you need
● Previous benchmark explains why it is
good to query only for fields you need to
process the current request
● All the fields you don’t query for, will still
be available in the object with None value
Evolving the Schema
● Migrations are performed lazily as the
objects are loaded from the database
● Simple schema evolutions:
○ New field: It will just be None for old entities.
○ Removed: Declare it as ming.schema.Deprecated
○ Changed Type: Declare it as ming.schema.Migrate
● Complex schema evolutions:
○ Add a migration function in __mongometa__
Complex migrations with Ming
class OldWikiPage(Document):
_id = Field(schema.ObjectId)
title = Field(str)
text = Field(str, if_missing='')
metadata = Field(dict(tags=[str], categories=[str]))
class WikiPage(Document):
class __mongometa__:
session = DBSession
name = 'wiki_page'
version_of = OldWikiPage
def migrate(data):
result = dict(data, version=1, tags=data['metadata']['tags'],
categories=data['metadata']['categories'])
del result['metadata']
return result
version = Field(1, required=True)
# … more fields ...
Testing MongoDB
● Ming makes testing easy
○ Your models can be directly imported from tests
○ Just bind the session to a DataStorage created in
your tests suite
● Ming provides MongoInMemory
○ much like sqlite://:memory:
● Implements 90% of mongodb, including
javascript execution with spidermonkey
Ming for Web Applications
● Ming can be integrated in any WSGI
framework through the ming.odm.
middleware.MingMiddleware
○ Automatically disposes open sessions at the end
of requests
○ Automatically provides session flushing
○ Automatically clears the session in case of
exceptions
Ming with TurboGears
● Provides builtin support for ming
○ $ gearbox quickstart --ming projectname
● Ready made test suite with fixtures on MIM
● Facilities to debug and benchmark Ming
queries through the DebugBar
● TurboGears Admin automatically
generates CRUD from Ming models
Debugging MongoDB
● TurboGears debugbar has builtin support
for MongoDB
○ Executed queries logging and results
○ Queries timing
○ Syntax prettifier and highlight for Map-Reduce and
$where javascript code
○ Queries tracking on logs for performance
reporting of webservices
DebugBar in action
Ming without learning MongoDB
● Transition from SQL/Relational solutions
to MongoDB can be scary first time.
● You can use Sprox to lower the learning
cost for simple applications
○ Sprox is the library that empowers TurboGears
Admin to automatically generate pages from
SQLA or Ming
Sprox ORM abstractions
● ORMProvider, provides an abstraction over
the ORM
● ORMProviderSelector, automatically
detects the provider to use from a model.
● Mix those together and you have a db
independent layer with automatic storage
backend detection.
Hands on Sprox
● Provider.query(self, entity, **kwargs) → get all objects
of a collection
● Provider.get_obj(self, entity, params) → get an object
● Provider.update(self, entity, params) → update an
object
● Provider.create(self, entity, params) → create a new
object
# Sprox (Ming or SQLAlchemy)
count, transactions = provider.query(MoneyTransfer)
transactions = DBSession.query(MoneyTransfer).all() # SQLAlchemy
transactions = MoneyTransfer.query.find().all() # Ming
Questions?

Más contenido relacionado

La actualidad más candente

HTML5 - The Good, the Bad, the Ugly
HTML5 - The Good, the Bad, the UglyHTML5 - The Good, the Bad, the Ugly
HTML5 - The Good, the Bad, the Ugly
Mario Heiderich
 
Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...
Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...
Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...
Mario Heiderich
 

La actualidad más candente (10)

ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 3/3 - Web components avec ...
ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 3/3 - Web components avec ...ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 3/3 - Web components avec ...
ENIB 2015-2016 - CAI Web - S01E01- Côté navigateur 3/3 - Web components avec ...
 
HTML, CSS & Javascript Architecture (extended version) - Jan Kraus
HTML, CSS & Javascript Architecture (extended version) - Jan KrausHTML, CSS & Javascript Architecture (extended version) - Jan Kraus
HTML, CSS & Javascript Architecture (extended version) - Jan Kraus
 
Going offline with JS (DDD Sydney)
Going offline with JS (DDD Sydney)Going offline with JS (DDD Sydney)
Going offline with JS (DDD Sydney)
 
まよいの墓(WebVR編)
まよいの墓(WebVR編)まよいの墓(WebVR編)
まよいの墓(WebVR編)
 
Devoxx France - Web Components, Polymer et Material Design
Devoxx France -  Web Components, Polymer et Material DesignDevoxx France -  Web Components, Polymer et Material Design
Devoxx France - Web Components, Polymer et Material Design
 
"How to use TypeORM and stay alive", Andrii Andriiko
"How to use TypeORM and stay alive", Andrii Andriiko"How to use TypeORM and stay alive", Andrii Andriiko
"How to use TypeORM and stay alive", Andrii Andriiko
 
Pyramid of-developer-skills
Pyramid of-developer-skillsPyramid of-developer-skills
Pyramid of-developer-skills
 
ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 3/3 - Web Components avec Po...
ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 3/3 - Web Components avec Po...ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 3/3 - Web Components avec Po...
ENIB 2015 2016 - CAI Web S02E01- Côté Navigateur 3/3 - Web Components avec Po...
 
HTML5 - The Good, the Bad, the Ugly
HTML5 - The Good, the Bad, the UglyHTML5 - The Good, the Bad, the Ugly
HTML5 - The Good, the Bad, the Ugly
 
Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...
Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...
Copy & Pest - A case-study on the clipboard, blind trust and invisible cross-...
 

Destacado

Achieving Maximum Results from Your Hostel
Achieving Maximum Results from Your HostelAchieving Maximum Results from Your Hostel
Achieving Maximum Results from Your Hostel
GoMio.com
 
planeamiento estratégico, paradigmas, cambio, entorno
planeamiento estratégico, paradigmas, cambio, entornoplaneamiento estratégico, paradigmas, cambio, entorno
planeamiento estratégico, paradigmas, cambio, entorno
UNIVERSIDAD NACIONAL DE PIURA
 

Destacado (9)

Tell Your Story: Select Social PR Case Studies 2015
Tell Your Story: Select Social PR Case Studies 2015Tell Your Story: Select Social PR Case Studies 2015
Tell Your Story: Select Social PR Case Studies 2015
 
Achieving Maximum Results from Your Hostel
Achieving Maximum Results from Your HostelAchieving Maximum Results from Your Hostel
Achieving Maximum Results from Your Hostel
 
Principles Of Achieving Wealth
Principles Of Achieving WealthPrinciples Of Achieving Wealth
Principles Of Achieving Wealth
 
TraDesto Financial Social Network
TraDesto Financial Social NetworkTraDesto Financial Social Network
TraDesto Financial Social Network
 
Tell Your Story Capabilities & Cases 2014
Tell Your Story Capabilities & Cases 2014Tell Your Story Capabilities & Cases 2014
Tell Your Story Capabilities & Cases 2014
 
PyConUK 2014 - PostMortem Debugging and Web Development Updated
PyConUK 2014 - PostMortem Debugging and Web Development UpdatedPyConUK 2014 - PostMortem Debugging and Web Development Updated
PyConUK 2014 - PostMortem Debugging and Web Development Updated
 
Linked in
Linked inLinked in
Linked in
 
planeamiento estratégico, paradigmas, cambio, entorno
planeamiento estratégico, paradigmas, cambio, entornoplaneamiento estratégico, paradigmas, cambio, entorno
planeamiento estratégico, paradigmas, cambio, entorno
 
EuroPython 2013 - Python3 TurboGears Training
EuroPython 2013 - Python3 TurboGears TrainingEuroPython 2013 - Python3 TurboGears Training
EuroPython 2013 - Python3 TurboGears Training
 

Similar a PyConUK2013 - Validated documents on MongoDB with Ming

Tech meetup: Web Applications Performance
Tech meetup: Web Applications PerformanceTech meetup: Web Applications Performance
Tech meetup: Web Applications Performance
Santex Group
 
PyConIT6 - Messing up with pymongo for fun and profit
PyConIT6 - Messing up with pymongo for fun and profitPyConIT6 - Messing up with pymongo for fun and profit
PyConIT6 - Messing up with pymongo for fun and profit
Alessandro Molina
 

Similar a PyConUK2013 - Validated documents on MongoDB with Ming (20)

JavascriptMVC: Another choice of web framework
JavascriptMVC: Another choice of web frameworkJavascriptMVC: Another choice of web framework
JavascriptMVC: Another choice of web framework
 
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
EuroPython 2013 - FAST, DOCUMENTED AND RELIABLE JSON BASED WEBSERVICES WITH P...
 
Robust C++ Task Systems Through Compile-time Checks
Robust C++ Task Systems Through Compile-time ChecksRobust C++ Task Systems Through Compile-time Checks
Robust C++ Task Systems Through Compile-time Checks
 
Using FXML on Clojure
Using FXML on ClojureUsing FXML on Clojure
Using FXML on Clojure
 
Tech meetup: Web Applications Performance
Tech meetup: Web Applications PerformanceTech meetup: Web Applications Performance
Tech meetup: Web Applications Performance
 
More on gdb for my sql db as (fosdem 2016)
More on gdb for my sql db as (fosdem 2016)More on gdb for my sql db as (fosdem 2016)
More on gdb for my sql db as (fosdem 2016)
 
Joomla!Day Poland 2013 - Joomla Architecture (Ofer Cohen)
Joomla!Day Poland 2013 - Joomla Architecture  (Ofer Cohen)Joomla!Day Poland 2013 - Joomla Architecture  (Ofer Cohen)
Joomla!Day Poland 2013 - Joomla Architecture (Ofer Cohen)
 
PyConIT6 - Messing up with pymongo for fun and profit
PyConIT6 - Messing up with pymongo for fun and profitPyConIT6 - Messing up with pymongo for fun and profit
PyConIT6 - Messing up with pymongo for fun and profit
 
FOSDEM 2015: gdb tips and tricks for MySQL DBAs
FOSDEM 2015: gdb tips and tricks for MySQL DBAsFOSDEM 2015: gdb tips and tricks for MySQL DBAs
FOSDEM 2015: gdb tips and tricks for MySQL DBAs
 
Go Is Your Next Language — Sergii Shapoval
Go Is Your Next Language — Sergii ShapovalGo Is Your Next Language — Sergii Shapoval
Go Is Your Next Language — Sergii Shapoval
 
Mockist vs. Classicists TDD
Mockist vs. Classicists TDDMockist vs. Classicists TDD
Mockist vs. Classicists TDD
 
MongoTorino 2013 - BSON Mad Science for fun and profit
MongoTorino 2013 - BSON Mad Science for fun and profitMongoTorino 2013 - BSON Mad Science for fun and profit
MongoTorino 2013 - BSON Mad Science for fun and profit
 
Django Mongodb Engine
Django Mongodb EngineDjango Mongodb Engine
Django Mongodb Engine
 
Revealing ALLSTOCKER
Revealing ALLSTOCKERRevealing ALLSTOCKER
Revealing ALLSTOCKER
 
Deep dive into Android async operations
Deep dive into Android async operationsDeep dive into Android async operations
Deep dive into Android async operations
 
FrontEnd.pdf
FrontEnd.pdfFrontEnd.pdf
FrontEnd.pdf
 
Sharable of qualities of clean code
Sharable of qualities of clean codeSharable of qualities of clean code
Sharable of qualities of clean code
 
Критика "библиотечного" подхода в разработке под Android. UA Mobile 2016.
Критика "библиотечного" подхода в разработке под Android. UA Mobile 2016.Критика "библиотечного" подхода в разработке под Android. UA Mobile 2016.
Критика "библиотечного" подхода в разработке под Android. UA Mobile 2016.
 
Mantri Presentation One
Mantri Presentation OneMantri Presentation One
Mantri Presentation One
 
Gdb basics for my sql db as (openfest 2017) final
Gdb basics for my sql db as (openfest 2017) finalGdb basics for my sql db as (openfest 2017) final
Gdb basics for my sql db as (openfest 2017) final
 

Más de Alessandro Molina

Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2
Alessandro Molina
 
Rapid Prototyping with TurboGears2
Rapid Prototyping with TurboGears2Rapid Prototyping with TurboGears2
Rapid Prototyping with TurboGears2
Alessandro Molina
 
TurboGears2 Pluggable Applications
TurboGears2 Pluggable ApplicationsTurboGears2 Pluggable Applications
TurboGears2 Pluggable Applications
Alessandro Molina
 
From SQLAlchemy to Ming with TurboGears2
From SQLAlchemy to Ming with TurboGears2From SQLAlchemy to Ming with TurboGears2
From SQLAlchemy to Ming with TurboGears2
Alessandro Molina
 

Más de Alessandro Molina (12)

PyCon Ireland 2022 - PyArrow full stack.pdf
PyCon Ireland 2022 - PyArrow full stack.pdfPyCon Ireland 2022 - PyArrow full stack.pdf
PyCon Ireland 2022 - PyArrow full stack.pdf
 
PyconIE 2016 - Kajiki, the fast and validated template engine your were looki...
PyconIE 2016 - Kajiki, the fast and validated template engine your were looki...PyconIE 2016 - Kajiki, the fast and validated template engine your were looki...
PyconIE 2016 - Kajiki, the fast and validated template engine your were looki...
 
EP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
EP2016 - Moving Away From Nodejs To A Pure Python Solution For AssetsEP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
EP2016 - Moving Away From Nodejs To A Pure Python Solution For Assets
 
EuroPython 2015 - Storing files for the web is not as straightforward as you ...
EuroPython 2015 - Storing files for the web is not as straightforward as you ...EuroPython 2015 - Storing files for the web is not as straightforward as you ...
EuroPython 2015 - Storing files for the web is not as straightforward as you ...
 
PyConIT6 - MAKING SESSIONS AND CACHING ROOMMATES
PyConIT6 - MAKING SESSIONS AND CACHING ROOMMATESPyConIT6 - MAKING SESSIONS AND CACHING ROOMMATES
PyConIT6 - MAKING SESSIONS AND CACHING ROOMMATES
 
PyConFR 2014 - DEPOT, Story of a file.write() gone wrong
PyConFR 2014 - DEPOT, Story of a file.write() gone wrongPyConFR 2014 - DEPOT, Story of a file.write() gone wrong
PyConFR 2014 - DEPOT, Story of a file.write() gone wrong
 
Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2Reactive & Realtime Web Applications with TurboGears2
Reactive & Realtime Web Applications with TurboGears2
 
Post-Mortem Debugging and Web Development
Post-Mortem Debugging and Web DevelopmentPost-Mortem Debugging and Web Development
Post-Mortem Debugging and Web Development
 
PyGrunn2013 High Performance Web Applications with TurboGears
PyGrunn2013  High Performance Web Applications with TurboGearsPyGrunn2013  High Performance Web Applications with TurboGears
PyGrunn2013 High Performance Web Applications with TurboGears
 
Rapid Prototyping with TurboGears2
Rapid Prototyping with TurboGears2Rapid Prototyping with TurboGears2
Rapid Prototyping with TurboGears2
 
TurboGears2 Pluggable Applications
TurboGears2 Pluggable ApplicationsTurboGears2 Pluggable Applications
TurboGears2 Pluggable Applications
 
From SQLAlchemy to Ming with TurboGears2
From SQLAlchemy to Ming with TurboGears2From SQLAlchemy to Ming with TurboGears2
From SQLAlchemy to Ming with TurboGears2
 

Último

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Último (20)

Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...Apidays New York 2024 - The value of a flexible API Management solution for O...
Apidays New York 2024 - The value of a flexible API Management solution for O...
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 

PyConUK2013 - Validated documents on MongoDB with Ming

  • 1. VALIDATED DOCUMENTS ON MONGODB WITH MING Alessandro Molina @__amol__ amol@turbogears.org
  • 2. Who am I ● CTO @ Axant.it, mostly Python company (with some iOS and Android) ● TurboGears development team member ● Contributions to Ming project ODM layer ● Really happy to be here at PyConUK! ○ I thought I would have crashed my car driving on the wrong side!
  • 3. MongoDB Models ● Schema free ○ It looks like you don’t have a schema, but your code depends on properties that need to be there. ● SubDocuments ○ You know that a blog post contain a list of comments, but what it is a comment? ● Relations ○ You don’t have joins and foreign keys, but you still need to express relationships
  • 4. What’s Ming? ● MongoDB toolkit ○ Validation layer on pymongo ○ Manages schema migrations ○ In Memory MongoDB ○ ODM on top of all of those ● Born at sourceforge.net ● Supported by TurboGears community MongoDB PyMongo Ming Ming.ODM
  • 5. Getting Started with the ODM ● Ming.ODM looks like SQLAlchemy ● UnitOfWork ○ Avoid half-saved changes in case of crashes ○ Flush all your changes at once ● IdentityMap ○ Same DB objects are the same object in memory ● Supports Relations ● Supports events (after_insert, before_update, …)
  • 6. Declaring Schema with the ODM class WikiPage(MappedClass): # Metadata for the collection # like its name, indexes, session, ... class __mongometa__: session = DBSession name = 'wiki_page' unique_indexes = [('title',)] _id = FieldProperty(schema.ObjectId) title = FieldProperty(schema.String) text = FieldProperty(schema.String) # Ming automatically generates # the relationship query comments = RelationProperty('WikiComment') class WikiComment(MappedClass): class __mongometa__: session = DBSession name = 'wiki_comment' _id = FieldProperty(schema.ObjectId) text=FieldProperty(s.String, if_missing='') # Provides an actual relation point # between comments and pages page_id = ForeignIdProperty('WikiPage') ● Declarative interface for models ● Supports polymorphic models
  • 7. Querying the ODM wp = WikiPage.query.get(title='FirstPage') # Identity map prevents duplicates wp2 = WikiPage.query.get(title='FirstPage') assert wp is wp2 # manually fetching related comments comments = WikiComment.query.find(dict(page_id=wp._id)).all() # or comments = wp.comments # gets last 5 wikipages in natural order wps = WikiPage.query.find().sort('$natural', DESCENDING).limit(5).all() ● Query language tries to be natural for both SQLAlchemy and MongoDB users
  • 8. The Unit Of Work ● Flush or Clear the pending changes ● Avoid mixing UOW and atomic operations ● UnitOfWork as a cache wp = WikiPage(title='FirstPage', text='This is my first page') DBSession.flush() wp.title = "TITLE 2" DBSession.update(WikiPage, {'_id':wp._id}, {'$set': {'title': "TITLE 3"}}) DBSession.flush() # wp.title will be TITLE 2, not TITLE 3 wp2 = DBSession.get(WikiPage, wp._id) # wp2 lookup won’t query the database again
  • 9. How Validation works ● Ming documents are validated at certain points in their life cycle ○ When saving the document to the database ○ When loading it from the database. ○ Additionally, validation is performed when the document is created through the ODM layer or using the .make() method ■ Happens before they get saved for real
  • 10. Cost of Validation ● MongoDB is famous for its speed, but validation has a cost ○ MongoDB documents can contain many subdocuments ○ Each subdocument must be validated by ming ○ Can even contain lists of multiple subdocuments
  • 11. Cost of Validation benchmark #With Validation class User(MappedClass): # ... friends = FieldProperty([dict(fbuser=s.String, photo=s.String, name=s.String)], if_missing=[]) >>> timeit.timeit('User.query.find().all()', number=20000) 31.97218942642212 #Without Validation class User(MappedClass): # ... friends = FieldProperty(s.Anything, if_missing=[]) >>> timeit.timeit('User.query.find().all()', number=20000) 23.391359090805054 #Avoiding the field at query time >>> timeit.timeit('User.query.find({}, fields=("_id","name")).all()', number=20000) 21.58667516708374
  • 12. Only query what you need ● Previous benchmark explains why it is good to query only for fields you need to process the current request ● All the fields you don’t query for, will still be available in the object with None value
  • 13. Evolving the Schema ● Migrations are performed lazily as the objects are loaded from the database ● Simple schema evolutions: ○ New field: It will just be None for old entities. ○ Removed: Declare it as ming.schema.Deprecated ○ Changed Type: Declare it as ming.schema.Migrate ● Complex schema evolutions: ○ Add a migration function in __mongometa__
  • 14. Complex migrations with Ming class OldWikiPage(Document): _id = Field(schema.ObjectId) title = Field(str) text = Field(str, if_missing='') metadata = Field(dict(tags=[str], categories=[str])) class WikiPage(Document): class __mongometa__: session = DBSession name = 'wiki_page' version_of = OldWikiPage def migrate(data): result = dict(data, version=1, tags=data['metadata']['tags'], categories=data['metadata']['categories']) del result['metadata'] return result version = Field(1, required=True) # … more fields ...
  • 15. Testing MongoDB ● Ming makes testing easy ○ Your models can be directly imported from tests ○ Just bind the session to a DataStorage created in your tests suite ● Ming provides MongoInMemory ○ much like sqlite://:memory: ● Implements 90% of mongodb, including javascript execution with spidermonkey
  • 16. Ming for Web Applications ● Ming can be integrated in any WSGI framework through the ming.odm. middleware.MingMiddleware ○ Automatically disposes open sessions at the end of requests ○ Automatically provides session flushing ○ Automatically clears the session in case of exceptions
  • 17. Ming with TurboGears ● Provides builtin support for ming ○ $ gearbox quickstart --ming projectname ● Ready made test suite with fixtures on MIM ● Facilities to debug and benchmark Ming queries through the DebugBar ● TurboGears Admin automatically generates CRUD from Ming models
  • 18. Debugging MongoDB ● TurboGears debugbar has builtin support for MongoDB ○ Executed queries logging and results ○ Queries timing ○ Syntax prettifier and highlight for Map-Reduce and $where javascript code ○ Queries tracking on logs for performance reporting of webservices
  • 20. Ming without learning MongoDB ● Transition from SQL/Relational solutions to MongoDB can be scary first time. ● You can use Sprox to lower the learning cost for simple applications ○ Sprox is the library that empowers TurboGears Admin to automatically generate pages from SQLA or Ming
  • 21. Sprox ORM abstractions ● ORMProvider, provides an abstraction over the ORM ● ORMProviderSelector, automatically detects the provider to use from a model. ● Mix those together and you have a db independent layer with automatic storage backend detection.
  • 22. Hands on Sprox ● Provider.query(self, entity, **kwargs) → get all objects of a collection ● Provider.get_obj(self, entity, params) → get an object ● Provider.update(self, entity, params) → update an object ● Provider.create(self, entity, params) → create a new object # Sprox (Ming or SQLAlchemy) count, transactions = provider.query(MoneyTransfer) transactions = DBSession.query(MoneyTransfer).all() # SQLAlchemy transactions = MoneyTransfer.query.find().all() # Ming