SlideShare uma empresa Scribd logo
1 de 38
Pro ORM
Alex Gaynor
@alex_gaynor




               Django NYC
What is this talk?
  ORM Architecture   Practical Things




        50%          50%
ORM Architecture
QuerySet-Refactor
• A big refactor of the ORM internals
• Happened a bit before Django 1.0

   Old                      New
Multi DB
• GSOC project this past summer
• Added multiple database support to
  Django

• Ripped up a lot of internals, and then
  put them back together

   Old                      New
from django.db import models

class MyModel(models.Model):
    pass



                               MyModel.objects




                 Managers
class Manager(object):
    def get_query_set(self):
       return QuerySet(self.model)

    def get(self, *args, **kwargs):
        return self.get_query_set().get(*args, **kwargs)

    def filter(self, *args, **kwargs):
        return self.get_query_set().filter(*args, **kwargs)

    # ETC...




    get_query_set(), your
    gateway to the rabbit
QuerySet
• Backend agnostic
• Basically it handles turning the public
  API into calls to methods on Query

• Surprisingly little meat for a 1400
  line file

• Also, a few subclasses for values(),
  values_list(), and dates()
Query
• This part is backend specific, SQL vs.
  GAE here, not Postgres vs. Oracle
• It carries all the info around, ordering,
  joins, where, aggregates, etc...
• It used to generate SQL, not anymore
  (more on this later)
self.model = model
self.alias_refcount = {}
self.alias_map = {}
self.table_map = {}
self.join_map = {}
self.rev_join_map = {}
self.quote_cache = {}
self.default_cols = True
self.default_ordering = True
self.standard_ordering = True
self.ordering_aliases = []
self.select_fields = []
self.related_select_fields = []
self.dupe_avoidance = {}
self.used_aliases = set()
self.filter_is_sticky = False
self.included_inherited_models = {}
self.select = []
self.tables = []
self.where = where()
self.where_class = where
self.group_by = None
self.having = where()
self.order_by = []
self.low_mark, self.high_mark = 0, None
self.distinct = False
self.select_related = False
self.related_select_cols = []
self.aggregates = SortedDict()
self.aggregate_select_mask = None
self._aggregate_select_cache = None
self.max_depth = 5
self.extra = SortedDict()
self.extra_select_mask = None
self._extra_select_cache = None
self.extra_tables = ()
self.extra_order_by = ()
self.deferred_loading = (set(), True)
I told you it was a lot of
          stuff
The Major Players
   Attributes            Methods
   self.where       self.get_compiler()
  self.having          self.clone()
self.aggregates         self.join()
 self.alias_map      self.add_filter()
self.select_fields   self.add_ordering()
Dude, where’s my
         SQL?
There are no relevant images for SQL, so
you get to settle for me trying to be funny
SQLCompiler

• Takes Querys and turns ‘em into SQL.
• Also executes SQL.
• This handles the backend specific
  stuff.

• We ship 2 sets of them. 1 for Oracle,
  and one for pretty much everything
  else.
31 Flavors!

  SQLCompiler        SQLInsertCompiler

SQLDeleteCompiler     SQLDateCompiler

SQLUpdateCompiler   SQLAggregateCompiler
django.db.backends.*
• Interoperate with    • Running the cmd line
  database drivers       shell

• Handle most of the   • django.contrib.gis.db.
  nuances of the         backends
  various databases’
  SQL dialects

• DDL for creation
• Introspection
Putting this Stuff to
     Good Use
aka the part you might use at your day
                 job
Custom Aggregates
• Django comes with a few aggregates
                     django.db.models.aggregates
                                Avg
• But databases
  have other                   Count
  aggregates                    Max

• Some of them                  Min
  even let you                 StdDev
  create your own!
                                Sum
                              Variance
Aggregates Come in Two
        Parts
• One part is a data carrier, it knows
  what field you’re aggregating over.
• The other part turns that into SQL.
• Starting to sound familiar?
Part I
from django.db.models import Aggregate


class MyAggregate(Aggregate):
    def add_to_query(self, query, alias, col, course,
        is_summary):
        aggregate = SQLMyAggregate(col, source=source,
            is_summary=is_summary, **extra)
        query.aggregates[alias] = aggregate
Part II
from django.db.models.sql.aggregates import 
    Aggregate as SQLAggregate


class SQLMyAggregate(SQLAggregate):
    sql_template = "%(function)(cast(%(field)s as numeric) / 100)"
    sql_function = "MYFUNCTION"
    is_ordinal = True
Automatic Caching
Single Object Caching
• Basically we want to automatically
  cache any get() lookups on unique
  fields (primary key, slugs, etc.)

• These types of queries seem to pop up
  a lot (think every single foreign key
  traversal)
• Also automatically do invalidation for
  us.
from django.core.cache import cache
from django.db.models.query import QuerySet


class CachingQuerySet(QuerySet):
    def get(self, *args, **kwargs):
        sup = lambda: super(CachingQuerySet, self). 
            get(*args, **kwargs)
        if len(args) != 1 or not kwargs or self.query.where:
            return sup()
        key, value = kwargs.iteritems().next()
        if key.endswith("__exact"):
            key = key[:-len("__exact")]
        if key not in ["pk", self.model._meta.pk.name]:
            return sup()
        cache_key = "%s:%s:%s" % (
            self.model._meta.app_label,
            self.model._meta.object_name,
            value
        )
        obj = cache.get(cache_key)
        if obj is not None:
            return obj
        obj = sup()
        cache.set(cache_key, obj)
        return obj
from django.db.models.signals import pre_save, pre_delete


class CachingManager(QuerySet):
    use_for_related_fields = True

    def get_query_set(self):
        return CachingQuerySet(self.model)

    def contribute_to_class(self, *args, **kwargs):
        super(CachingManager, self). 
            contribute_to_class(*args, **kwargs)
        pre_save.connect(invalidate_cache, self.model)
        pre_delete.connect(invalidate_cache, self.model)
def invalide_cache(instance, sender, **kwargs):
    cache_key = "%s:%s:%s" % (
        instance._meta.app_label,
        instance._meta.object_name,
        instance.pk
    )
    cache.delete(cache_key)




       Aaand, Done!
Questions?
Extra
Custom Field Review
Methods

                          Converts value from
   to_python
                        serialized form to Python

    validate               Performs validation

    db_type             Returns the database type

                          Performs DB agnostic
 get_prep_value
                         coercion and validation
                          DB specific coercion/
get_db_prep_value
                               validation

    formfield              Provides a form field

Mais conteúdo relacionado

Mais procurados

Building DSLs With Eclipse
Building DSLs With EclipseBuilding DSLs With Eclipse
Building DSLs With EclipsePeter Friese
 
Art of Javascript
Art of JavascriptArt of Javascript
Art of JavascriptTarek Yehia
 
Advanced php
Advanced phpAdvanced php
Advanced phphamfu
 
Entities in drupal 7
Entities in drupal 7Entities in drupal 7
Entities in drupal 7Zsolt Tasnadi
 
Top Ten Reasons to Use EntityFieldQuery in Drupal
Top Ten Reasons to Use EntityFieldQuery in DrupalTop Ten Reasons to Use EntityFieldQuery in Drupal
Top Ten Reasons to Use EntityFieldQuery in DrupalFredric Mitchell
 
Entity Query API
Entity Query APIEntity Query API
Entity Query APImarcingy
 
ERRest - The Next Steps
ERRest - The Next StepsERRest - The Next Steps
ERRest - The Next StepsWO Community
 
jQuery Fundamentals
jQuery FundamentalsjQuery Fundamentals
jQuery FundamentalsGil Fink
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 MinutesAzim Kurt
 
JQuery Presentation
JQuery PresentationJQuery Presentation
JQuery PresentationSony Jain
 
Apache Solr Search Mastery
Apache Solr Search MasteryApache Solr Search Mastery
Apache Solr Search MasteryAcquia
 

Mais procurados (20)

J query
J queryJ query
J query
 
jQuery
jQueryjQuery
jQuery
 
J query1
J query1J query1
J query1
 
Building DSLs With Eclipse
Building DSLs With EclipseBuilding DSLs With Eclipse
Building DSLs With Eclipse
 
Art of Javascript
Art of JavascriptArt of Javascript
Art of Javascript
 
Advanced php
Advanced phpAdvanced php
Advanced php
 
Entities in drupal 7
Entities in drupal 7Entities in drupal 7
Entities in drupal 7
 
ERRest in Depth
ERRest in DepthERRest in Depth
ERRest in Depth
 
Top Ten Reasons to Use EntityFieldQuery in Drupal
Top Ten Reasons to Use EntityFieldQuery in DrupalTop Ten Reasons to Use EntityFieldQuery in Drupal
Top Ten Reasons to Use EntityFieldQuery in Drupal
 
Entity Query API
Entity Query APIEntity Query API
Entity Query API
 
ERRest - The Next Steps
ERRest - The Next StepsERRest - The Next Steps
ERRest - The Next Steps
 
jQuery Fundamentals
jQuery FundamentalsjQuery Fundamentals
jQuery Fundamentals
 
Drupal7 dbtng
Drupal7  dbtngDrupal7  dbtng
Drupal7 dbtng
 
Your Entity, Your Code
Your Entity, Your CodeYour Entity, Your Code
Your Entity, Your Code
 
50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes50 Laravel Tricks in 50 Minutes
50 Laravel Tricks in 50 Minutes
 
JQuery Presentation
JQuery PresentationJQuery Presentation
JQuery Presentation
 
Drupal 8 database api
Drupal 8 database apiDrupal 8 database api
Drupal 8 database api
 
Apache Solr Search Mastery
Apache Solr Search MasteryApache Solr Search Mastery
Apache Solr Search Mastery
 
jQuery Essentials
jQuery EssentialsjQuery Essentials
jQuery Essentials
 
jQuery Selectors
jQuery SelectorsjQuery Selectors
jQuery Selectors
 

Semelhante a Django Pro ORM

Data Migrations in the App Engine Datastore
Data Migrations in the App Engine DatastoreData Migrations in the App Engine Datastore
Data Migrations in the App Engine DatastoreRyan Morlok
 
DjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling DisqusDjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling Disquszeeg
 
Django Multi-DB in Anger
Django Multi-DB in AngerDjango Multi-DB in Anger
Django Multi-DB in AngerLoren Davie
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethodsdreampuf
 
Bye bye $GLOBALS['TYPO3_DB']
Bye bye $GLOBALS['TYPO3_DB']Bye bye $GLOBALS['TYPO3_DB']
Bye bye $GLOBALS['TYPO3_DB']Jan Helke
 
Spring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffSpring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffJAX London
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenerytoddbr
 
High Performance Django 1
High Performance Django 1High Performance Django 1
High Performance Django 1DjangoCon2008
 
High Performance Django
High Performance DjangoHigh Performance Django
High Performance DjangoDjangoCon2008
 
Modules Building Presentation
Modules Building PresentationModules Building Presentation
Modules Building Presentationhtyson
 
Javascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & AngularJavascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & AngularErik Guzman
 

Semelhante a Django Pro ORM (20)

Data Migrations in the App Engine Datastore
Data Migrations in the App Engine DatastoreData Migrations in the App Engine Datastore
Data Migrations in the App Engine Datastore
 
DjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling DisqusDjangoCon 2010 Scaling Disqus
DjangoCon 2010 Scaling Disqus
 
Django Good Practices
Django Good PracticesDjango Good Practices
Django Good Practices
 
Django Multi-DB in Anger
Django Multi-DB in AngerDjango Multi-DB in Anger
Django Multi-DB in Anger
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethods
 
Bye bye $GLOBALS['TYPO3_DB']
Bye bye $GLOBALS['TYPO3_DB']Bye bye $GLOBALS['TYPO3_DB']
Bye bye $GLOBALS['TYPO3_DB']
 
Spring data requery
Spring data requerySpring data requery
Spring data requery
 
Django tricks (2)
Django tricks (2)Django tricks (2)
Django tricks (2)
 
Spring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffSpring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard Wolff
 
Javascript first-class citizenery
Javascript first-class citizeneryJavascript first-class citizenery
Javascript first-class citizenery
 
Django at Scale
Django at ScaleDjango at Scale
Django at Scale
 
High Performance Django 1
High Performance Django 1High Performance Django 1
High Performance Django 1
 
High Performance Django
High Performance DjangoHigh Performance Django
High Performance Django
 
Modules Building Presentation
Modules Building PresentationModules Building Presentation
Modules Building Presentation
 
Real World MVC
Real World MVCReal World MVC
Real World MVC
 
Javascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & AngularJavascript Memory leaks and Performance & Angular
Javascript Memory leaks and Performance & Angular
 
Data herding
Data herdingData herding
Data herding
 
Data herding
Data herdingData herding
Data herding
 
Scala and Spring
Scala and SpringScala and Spring
Scala and Spring
 
Jsp project module
Jsp project moduleJsp project module
Jsp project module
 

Último

Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 3652toLead Limited
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024BookNet Canada
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptxLBM Solutions
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 

Último (20)

Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
Tech-Forward - Achieving Business Readiness For Copilot in Microsoft 365
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
#StandardsGoals for 2024: What’s new for BISAC - Tech Forum 2024
 
Key Features Of Token Development (1).pptx
Key  Features Of Token  Development (1).pptxKey  Features Of Token  Development (1).pptx
Key Features Of Token Development (1).pptx
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 

Django Pro ORM

  • 2.
  • 3. What is this talk? ORM Architecture Practical Things 50% 50%
  • 6. • A big refactor of the ORM internals • Happened a bit before Django 1.0 Old New
  • 8. • GSOC project this past summer • Added multiple database support to Django • Ripped up a lot of internals, and then put them back together Old New
  • 9. from django.db import models class MyModel(models.Model): pass MyModel.objects Managers
  • 10. class Manager(object): def get_query_set(self): return QuerySet(self.model) def get(self, *args, **kwargs): return self.get_query_set().get(*args, **kwargs) def filter(self, *args, **kwargs): return self.get_query_set().filter(*args, **kwargs) # ETC... get_query_set(), your gateway to the rabbit
  • 11. QuerySet • Backend agnostic • Basically it handles turning the public API into calls to methods on Query • Surprisingly little meat for a 1400 line file • Also, a few subclasses for values(), values_list(), and dates()
  • 12. Query
  • 13.
  • 14. • This part is backend specific, SQL vs. GAE here, not Postgres vs. Oracle • It carries all the info around, ordering, joins, where, aggregates, etc... • It used to generate SQL, not anymore (more on this later)
  • 15. self.model = model self.alias_refcount = {} self.alias_map = {} self.table_map = {} self.join_map = {} self.rev_join_map = {} self.quote_cache = {} self.default_cols = True self.default_ordering = True self.standard_ordering = True self.ordering_aliases = [] self.select_fields = [] self.related_select_fields = [] self.dupe_avoidance = {} self.used_aliases = set() self.filter_is_sticky = False self.included_inherited_models = {} self.select = [] self.tables = [] self.where = where() self.where_class = where self.group_by = None self.having = where()
  • 16. self.order_by = [] self.low_mark, self.high_mark = 0, None self.distinct = False self.select_related = False self.related_select_cols = [] self.aggregates = SortedDict() self.aggregate_select_mask = None self._aggregate_select_cache = None self.max_depth = 5 self.extra = SortedDict() self.extra_select_mask = None self._extra_select_cache = None self.extra_tables = () self.extra_order_by = () self.deferred_loading = (set(), True)
  • 17. I told you it was a lot of stuff
  • 18. The Major Players Attributes Methods self.where self.get_compiler() self.having self.clone() self.aggregates self.join() self.alias_map self.add_filter() self.select_fields self.add_ordering()
  • 19. Dude, where’s my SQL? There are no relevant images for SQL, so you get to settle for me trying to be funny
  • 20. SQLCompiler • Takes Querys and turns ‘em into SQL. • Also executes SQL. • This handles the backend specific stuff. • We ship 2 sets of them. 1 for Oracle, and one for pretty much everything else.
  • 21. 31 Flavors! SQLCompiler SQLInsertCompiler SQLDeleteCompiler SQLDateCompiler SQLUpdateCompiler SQLAggregateCompiler
  • 22. django.db.backends.* • Interoperate with • Running the cmd line database drivers shell • Handle most of the • django.contrib.gis.db. nuances of the backends various databases’ SQL dialects • DDL for creation • Introspection
  • 23. Putting this Stuff to Good Use aka the part you might use at your day job
  • 25. • Django comes with a few aggregates django.db.models.aggregates Avg • But databases have other Count aggregates Max • Some of them Min even let you StdDev create your own! Sum Variance
  • 26. Aggregates Come in Two Parts • One part is a data carrier, it knows what field you’re aggregating over. • The other part turns that into SQL. • Starting to sound familiar?
  • 27. Part I from django.db.models import Aggregate class MyAggregate(Aggregate): def add_to_query(self, query, alias, col, course, is_summary): aggregate = SQLMyAggregate(col, source=source, is_summary=is_summary, **extra) query.aggregates[alias] = aggregate
  • 28. Part II from django.db.models.sql.aggregates import Aggregate as SQLAggregate class SQLMyAggregate(SQLAggregate): sql_template = "%(function)(cast(%(field)s as numeric) / 100)" sql_function = "MYFUNCTION" is_ordinal = True
  • 30.
  • 31. Single Object Caching • Basically we want to automatically cache any get() lookups on unique fields (primary key, slugs, etc.) • These types of queries seem to pop up a lot (think every single foreign key traversal) • Also automatically do invalidation for us.
  • 32.
  • 33. from django.core.cache import cache from django.db.models.query import QuerySet class CachingQuerySet(QuerySet): def get(self, *args, **kwargs): sup = lambda: super(CachingQuerySet, self). get(*args, **kwargs) if len(args) != 1 or not kwargs or self.query.where: return sup() key, value = kwargs.iteritems().next() if key.endswith("__exact"): key = key[:-len("__exact")] if key not in ["pk", self.model._meta.pk.name]: return sup() cache_key = "%s:%s:%s" % ( self.model._meta.app_label, self.model._meta.object_name, value ) obj = cache.get(cache_key) if obj is not None: return obj obj = sup() cache.set(cache_key, obj) return obj
  • 34. from django.db.models.signals import pre_save, pre_delete class CachingManager(QuerySet): use_for_related_fields = True def get_query_set(self): return CachingQuerySet(self.model) def contribute_to_class(self, *args, **kwargs): super(CachingManager, self). contribute_to_class(*args, **kwargs) pre_save.connect(invalidate_cache, self.model) pre_delete.connect(invalidate_cache, self.model)
  • 35. def invalide_cache(instance, sender, **kwargs): cache_key = "%s:%s:%s" % ( instance._meta.app_label, instance._meta.object_name, instance.pk ) cache.delete(cache_key) Aaand, Done!
  • 38. Methods Converts value from to_python serialized form to Python validate Performs validation db_type Returns the database type Performs DB agnostic get_prep_value coercion and validation DB specific coercion/ get_db_prep_value validation formfield Provides a form field

Notas do Editor