SlideShare a Scribd company logo
1 of 14
Download to read offline
Declarative Data Modeling 
in Python 
by Joshua Forman
Introducing valid_model 
It includes: 
- base class - Object 
- basic descriptors - Integer, Float, DateTime, String, ... 
- nesting descriptors - Dict, List, Set, EmbeddedObject
Most similar libraries are tightly integrated to a persistence layer: 
SQLAlchemy, Django ORM, mongokit, etc. 
Or are targeted at web forms: 
Formencode, colander, deform 
So the goal was to build a highly flexible unopinionated data modeling 
library.
Some Use Cases 
● Database data model 
● Form validation 
● Test fixtures 
● API request/response objects 
● Scrubbing and normalizing data 
● Data migration
car = { 
'make': None, 
'model': None, 
'doors': None, 
'horsepower': None, 
} 
class Car(object): 
def __init__(self, make=None, model=None, doors=None, 
horsepower=None): 
self.make = make 
self.model = model 
self.doors = doors 
self.horsepower = horsepower 
It is valid python to arbitrarily add new instance attributes in other methods, which can lead to 
headaches (and pylint complaints)
At least I know the fields ahead of time but what datatypes are these attributes? 
def horse_check(value): 
if value == 1: 
raise ValidationError('Is this powered by an actual horse?') 
elif value <= 0: 
raise ValidationError('Phantom horses?') 
return True 
class Car(Object): 
make = String(nullable=False) 
model = String() 
doors = Integer(validator=lambda x: x<=5) 
horsepower = Integer(validator=horse_check)
Nested Schemas is Easy 
class Person(Object): 
name = String(nullable=False) 
homepage = String() 
class BlogPost(Object): 
title = String(nullable=False, mutator=lambda x: x.title()) 
updated = DateTime(nullable=False, default=datetime.utcnow) 
published = DateTime() 
author = EmbeddedObject(Person) 
contributors = List(value=EmbeddedObject(Person), nullable=False) 
tags = List(value=String(nullable=False), nullable=False) 
def validate(self): 
super(BlogPost, self).validate() 
if self.published is not None and self.published > self.updated: 
raise ValidationError('a post cannot be published at a later date 
than it was updated') 
post = BlogPost(title='example post', author={'name': 'Josh'}, tags=['tag1', 'tag2']) 
>>> print post 
{'updated': datetime.datetime(2014, 10, 7, 13, 43, 1, 960174), 
'author': {'homepage': None, 'name': u'Josh'}, 
'contributors': [], 'title': u'Example Post', 'tags': [u'tag1', u'tag2'], 'published': None}
valid_model also provides something closer to strict typing 
class Car(Object): 
make = String(nullable=False) 
model = String() 
doors = Integer(validator=lambda x: x<=5) 
horsepower = Integer(validator=horse_check) 
>>> Car(doors='five') 
valid_model.exc.ValidationError: 'five' is not an int 
>>> Car(doors=10) 
valid_model.exc.ValidationError: doors 
>>> Car(horsepower=1) 
valid_model.exc.ValidationError: Is this powered by an actual horse? 
>>> Car(make=None) 
valid_model.exc.ValidationError: make is not nullable
Normalize your data when it gets set 
class HTTPAccessLog(Object): 
code = Integer(nullable=False) 
status = String(nullable=False, mutator=lambda x: x.upper()) 
timestamp = DateTime(default=datetime.utcnow) 
def validate(self): 
super(HTTPAccessLog, self).validate() 
if not self.status.startswith(unicode(self.code)): 
raise ValidationError('code and status do not match') 
>>> ping = HTTPAccessLog() 
>>> ping.code = 404 
>>> ping.status = '404 not found' 
>>> print ping 
{'status': u'404 NOT FOUND', 'timestamp': datetime.datetime(2014, 10, 7, 13, 36, 15, 217678), 
'code': 404}
Descriptors Tangent 
Python descriptors are fancy attributes. 
class SomeDescriptor(object): 
def __get__(self, instance, klass=None): 
…. 
def __set__(self, instance, value): 
…. 
def __del__(self, instance): 
…. 
class Foo(object): 
b = SomeDescriptor()
@property Descriptors 
@property is the most common 
class Foo(object): 
@property 
def a(self): 
return self._a 
@a.setter 
def a(self, value): 
self._a = value 
# Make an attribute readonly by not defining the setter. 
@property 
def readonly(self): 
return self._private_var 
#Lazily initialize or cache expensive calculations 
@property 
def expensive_func(self): 
if self._result is None: 
self._result = expensive_func() 
return self._result
Customizing Descriptors is Easy 
Extending existing descriptors works like subclassing anything else in python 
class SuperDateTime(DateTime): 
def __set__(self, instance, value): 
if isinstance(value, basestring): 
value = dateutils.parse(value) 
elif isinstance(value, (int, float)): 
value = datetime.utcfromtimestamp(value) 
super(SuperDateTime, self).__set__(instance, value) 
class Decimal(Generic): 
def __set__(self, instance, value): 
if not isinstance(value, decimal.Decimal): 
raise ValidationError('{} is not a decimal'.format(self.name)) 
super(Decimal, self).__set__(instance, value)
Simple wrappers for persistence 
An example of using MongoDB with Redis as a cache 
class PersistBlogPost(object): 
def __init__(self, mongo_collection, redis_conn): 
... 
def insert(self, post): 
self.mongo_collection.insert(post.__json__()) 
def find(self, title): 
post = self.redis_conn.get(title) 
if post: 
return pickle.loads(post) 
else: 
post = self.mongo_collection.find_one({'title': title}) 
if post: 
post = BlogPost(**post) 
self.redis_conn.set(title, pickle.dumps(post)) 
return post
Thank You 
http://github.com/outbrain/valid_model 
Joshua Forman 
jforman@outbrain.com

More Related Content

What's hot

Functions and Objects in JavaScript
Functions and Objects in JavaScript Functions and Objects in JavaScript
Functions and Objects in JavaScript Dhananjay Kumar
 
JavaScript - Chapter 6 - Basic Functions
 JavaScript - Chapter 6 - Basic Functions JavaScript - Chapter 6 - Basic Functions
JavaScript - Chapter 6 - Basic FunctionsWebStackAcademy
 
JavaScript - Chapter 8 - Objects
 JavaScript - Chapter 8 - Objects JavaScript - Chapter 8 - Objects
JavaScript - Chapter 8 - ObjectsWebStackAcademy
 
javascript objects
javascript objectsjavascript objects
javascript objectsVijay Kalyan
 
3.1 javascript objects_DOM
3.1 javascript objects_DOM3.1 javascript objects_DOM
3.1 javascript objects_DOMJalpesh Vasa
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 
Ios development
Ios developmentIos development
Ios developmentelnaqah
 
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYAPYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYAMaulik Borsaniya
 
ActionScript3 collection query API proposal
ActionScript3 collection query API proposalActionScript3 collection query API proposal
ActionScript3 collection query API proposalSlavisa Pokimica
 
Basics of Object Oriented Programming in Python
Basics of Object Oriented Programming in PythonBasics of Object Oriented Programming in Python
Basics of Object Oriented Programming in PythonSujith Kumar
 
Few simple-type-tricks in scala
Few simple-type-tricks in scalaFew simple-type-tricks in scala
Few simple-type-tricks in scalaRuslan Shevchenko
 
Powerful JavaScript Tips and Best Practices
Powerful JavaScript Tips and Best PracticesPowerful JavaScript Tips and Best Practices
Powerful JavaScript Tips and Best PracticesDragos Ionita
 
Oop in-php
Oop in-phpOop in-php
Oop in-phpRajesh S
 

What's hot (20)

Functions and Objects in JavaScript
Functions and Objects in JavaScript Functions and Objects in JavaScript
Functions and Objects in JavaScript
 
JavaScript - Chapter 6 - Basic Functions
 JavaScript - Chapter 6 - Basic Functions JavaScript - Chapter 6 - Basic Functions
JavaScript - Chapter 6 - Basic Functions
 
Python programming : Classes objects
Python programming : Classes objectsPython programming : Classes objects
Python programming : Classes objects
 
JavaScript - Chapter 8 - Objects
 JavaScript - Chapter 8 - Objects JavaScript - Chapter 8 - Objects
JavaScript - Chapter 8 - Objects
 
javascript objects
javascript objectsjavascript objects
javascript objects
 
3.1 javascript objects_DOM
3.1 javascript objects_DOM3.1 javascript objects_DOM
3.1 javascript objects_DOM
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 
Python oop class 1
Python oop   class 1Python oop   class 1
Python oop class 1
 
Csharp_Chap03
Csharp_Chap03Csharp_Chap03
Csharp_Chap03
 
Ios development
Ios developmentIos development
Ios development
 
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYAPYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
 
JavaScript Objects
JavaScript ObjectsJavaScript Objects
JavaScript Objects
 
ActionScript3 collection query API proposal
ActionScript3 collection query API proposalActionScript3 collection query API proposal
ActionScript3 collection query API proposal
 
Basics of Object Oriented Programming in Python
Basics of Object Oriented Programming in PythonBasics of Object Oriented Programming in Python
Basics of Object Oriented Programming in Python
 
Few simple-type-tricks in scala
Few simple-type-tricks in scalaFew simple-type-tricks in scala
Few simple-type-tricks in scala
 
Powerful JavaScript Tips and Best Practices
Powerful JavaScript Tips and Best PracticesPowerful JavaScript Tips and Best Practices
Powerful JavaScript Tips and Best Practices
 
Oop in-php
Oop in-phpOop in-php
Oop in-php
 
Parte II Objective C
Parte II   Objective CParte II   Objective C
Parte II Objective C
 
OOPs & Inheritance Notes
OOPs & Inheritance NotesOOPs & Inheritance Notes
OOPs & Inheritance Notes
 
Python advance
Python advancePython advance
Python advance
 

Similar to Declarative data modeling in Python with valid_model

constructors.pptx
constructors.pptxconstructors.pptx
constructors.pptxEpsiba1
 
Ruby Development and MongoMapper (John Nunemaker)
Ruby Development and MongoMapper (John Nunemaker)Ruby Development and MongoMapper (John Nunemaker)
Ruby Development and MongoMapper (John Nunemaker)MongoSF
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethodsdreampuf
 
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation StalOop2010 Scala Presentation Stal
Oop2010 Scala Presentation StalMichael Stal
 
Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Workhorse Computing
 
11. session 11 functions and objects
11. session 11   functions and objects11. session 11   functions and objects
11. session 11 functions and objectsPhúc Đỗ
 
PofEAA and SQLAlchemy
PofEAA and SQLAlchemyPofEAA and SQLAlchemy
PofEAA and SQLAlchemyInada Naoki
 
Scalable web application architecture
Scalable web application architectureScalable web application architecture
Scalable web application architecturepostrational
 
Pyimproved again
Pyimproved againPyimproved again
Pyimproved againrik0
 
Pyconie 2012
Pyconie 2012Pyconie 2012
Pyconie 2012Yaqi Zhao
 
CoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairCoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairMark
 
Building a Portfolio With Custom Post Types
Building a Portfolio With Custom Post TypesBuilding a Portfolio With Custom Post Types
Building a Portfolio With Custom Post TypesAlex Blackie
 

Similar to Declarative data modeling in Python with valid_model (20)

Oop java
Oop javaOop java
Oop java
 
constructors.pptx
constructors.pptxconstructors.pptx
constructors.pptx
 
Ruby Development and MongoMapper (John Nunemaker)
Ruby Development and MongoMapper (John Nunemaker)Ruby Development and MongoMapper (John Nunemaker)
Ruby Development and MongoMapper (John Nunemaker)
 
Python magicmethods
Python magicmethodsPython magicmethods
Python magicmethods
 
Python_Unit_2 OOPS.pptx
Python_Unit_2  OOPS.pptxPython_Unit_2  OOPS.pptx
Python_Unit_2 OOPS.pptx
 
Spsl vi unit final
Spsl vi unit finalSpsl vi unit final
Spsl vi unit final
 
Spsl v unit - final
Spsl v unit - finalSpsl v unit - final
Spsl v unit - final
 
Oop2010 Scala Presentation Stal
Oop2010 Scala Presentation StalOop2010 Scala Presentation Stal
Oop2010 Scala Presentation Stal
 
Real World MVC
Real World MVCReal World MVC
Real World MVC
 
Week3
Week3Week3
Week3
 
Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.Object Trampoline: Why having not the object you want is what you need.
Object Trampoline: Why having not the object you want is what you need.
 
Java scriptforjavadev part2a
Java scriptforjavadev part2aJava scriptforjavadev part2a
Java scriptforjavadev part2a
 
11. session 11 functions and objects
11. session 11   functions and objects11. session 11   functions and objects
11. session 11 functions and objects
 
PofEAA and SQLAlchemy
PofEAA and SQLAlchemyPofEAA and SQLAlchemy
PofEAA and SQLAlchemy
 
Scalable web application architecture
Scalable web application architectureScalable web application architecture
Scalable web application architecture
 
Pyimproved again
Pyimproved againPyimproved again
Pyimproved again
 
Pyconie 2012
Pyconie 2012Pyconie 2012
Pyconie 2012
 
CoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love AffairCoffeeScript - A Rubyist's Love Affair
CoffeeScript - A Rubyist's Love Affair
 
Building a Portfolio With Custom Post Types
Building a Portfolio With Custom Post TypesBuilding a Portfolio With Custom Post Types
Building a Portfolio With Custom Post Types
 
обзор Python
обзор Pythonобзор Python
обзор Python
 

Recently uploaded

SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendArshad QA
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 

Recently uploaded (20)

SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and Backend
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Exploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the ProcessExploring iOS App Development: Simplifying the Process
Exploring iOS App Development: Simplifying the Process
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 

Declarative data modeling in Python with valid_model

  • 1. Declarative Data Modeling in Python by Joshua Forman
  • 2. Introducing valid_model It includes: - base class - Object - basic descriptors - Integer, Float, DateTime, String, ... - nesting descriptors - Dict, List, Set, EmbeddedObject
  • 3. Most similar libraries are tightly integrated to a persistence layer: SQLAlchemy, Django ORM, mongokit, etc. Or are targeted at web forms: Formencode, colander, deform So the goal was to build a highly flexible unopinionated data modeling library.
  • 4. Some Use Cases ● Database data model ● Form validation ● Test fixtures ● API request/response objects ● Scrubbing and normalizing data ● Data migration
  • 5. car = { 'make': None, 'model': None, 'doors': None, 'horsepower': None, } class Car(object): def __init__(self, make=None, model=None, doors=None, horsepower=None): self.make = make self.model = model self.doors = doors self.horsepower = horsepower It is valid python to arbitrarily add new instance attributes in other methods, which can lead to headaches (and pylint complaints)
  • 6. At least I know the fields ahead of time but what datatypes are these attributes? def horse_check(value): if value == 1: raise ValidationError('Is this powered by an actual horse?') elif value <= 0: raise ValidationError('Phantom horses?') return True class Car(Object): make = String(nullable=False) model = String() doors = Integer(validator=lambda x: x<=5) horsepower = Integer(validator=horse_check)
  • 7. Nested Schemas is Easy class Person(Object): name = String(nullable=False) homepage = String() class BlogPost(Object): title = String(nullable=False, mutator=lambda x: x.title()) updated = DateTime(nullable=False, default=datetime.utcnow) published = DateTime() author = EmbeddedObject(Person) contributors = List(value=EmbeddedObject(Person), nullable=False) tags = List(value=String(nullable=False), nullable=False) def validate(self): super(BlogPost, self).validate() if self.published is not None and self.published > self.updated: raise ValidationError('a post cannot be published at a later date than it was updated') post = BlogPost(title='example post', author={'name': 'Josh'}, tags=['tag1', 'tag2']) >>> print post {'updated': datetime.datetime(2014, 10, 7, 13, 43, 1, 960174), 'author': {'homepage': None, 'name': u'Josh'}, 'contributors': [], 'title': u'Example Post', 'tags': [u'tag1', u'tag2'], 'published': None}
  • 8. valid_model also provides something closer to strict typing class Car(Object): make = String(nullable=False) model = String() doors = Integer(validator=lambda x: x<=5) horsepower = Integer(validator=horse_check) >>> Car(doors='five') valid_model.exc.ValidationError: 'five' is not an int >>> Car(doors=10) valid_model.exc.ValidationError: doors >>> Car(horsepower=1) valid_model.exc.ValidationError: Is this powered by an actual horse? >>> Car(make=None) valid_model.exc.ValidationError: make is not nullable
  • 9. Normalize your data when it gets set class HTTPAccessLog(Object): code = Integer(nullable=False) status = String(nullable=False, mutator=lambda x: x.upper()) timestamp = DateTime(default=datetime.utcnow) def validate(self): super(HTTPAccessLog, self).validate() if not self.status.startswith(unicode(self.code)): raise ValidationError('code and status do not match') >>> ping = HTTPAccessLog() >>> ping.code = 404 >>> ping.status = '404 not found' >>> print ping {'status': u'404 NOT FOUND', 'timestamp': datetime.datetime(2014, 10, 7, 13, 36, 15, 217678), 'code': 404}
  • 10. Descriptors Tangent Python descriptors are fancy attributes. class SomeDescriptor(object): def __get__(self, instance, klass=None): …. def __set__(self, instance, value): …. def __del__(self, instance): …. class Foo(object): b = SomeDescriptor()
  • 11. @property Descriptors @property is the most common class Foo(object): @property def a(self): return self._a @a.setter def a(self, value): self._a = value # Make an attribute readonly by not defining the setter. @property def readonly(self): return self._private_var #Lazily initialize or cache expensive calculations @property def expensive_func(self): if self._result is None: self._result = expensive_func() return self._result
  • 12. Customizing Descriptors is Easy Extending existing descriptors works like subclassing anything else in python class SuperDateTime(DateTime): def __set__(self, instance, value): if isinstance(value, basestring): value = dateutils.parse(value) elif isinstance(value, (int, float)): value = datetime.utcfromtimestamp(value) super(SuperDateTime, self).__set__(instance, value) class Decimal(Generic): def __set__(self, instance, value): if not isinstance(value, decimal.Decimal): raise ValidationError('{} is not a decimal'.format(self.name)) super(Decimal, self).__set__(instance, value)
  • 13. Simple wrappers for persistence An example of using MongoDB with Redis as a cache class PersistBlogPost(object): def __init__(self, mongo_collection, redis_conn): ... def insert(self, post): self.mongo_collection.insert(post.__json__()) def find(self, title): post = self.redis_conn.get(title) if post: return pickle.loads(post) else: post = self.mongo_collection.find_one({'title': title}) if post: post = BlogPost(**post) self.redis_conn.set(title, pickle.dumps(post)) return post
  • 14. Thank You http://github.com/outbrain/valid_model Joshua Forman jforman@outbrain.com