SlideShare a Scribd company logo
1 of 26
Download to read offline
Database madness with
         & SQL Alchemy

      Jaime Buelta
     jaime.buelta@gmail.com
 wrongsideofmemphis.worpress.com
A little about the project
●
    Online football management game
●
    Each user could get a club and control it
●
    We will import data about leagues, teams,
    players, etc from a partner
●
    As we are very optimistic, we are thinking on
    lots of players!
    ●
        Performance + non-relational data --> NoSQL
Pylons application
●
    Pylons is a “framework of frameworks”, as
    allow to custom made your own framework
●
    Very standard MVC structure
●
    RESTful URLs
●
    jinja2 for templates
●
    jQuery for the front end (JavaScript, AJAX)
Databases used
●
    MongoDB
●
    MS SQL Server
    ●
        Legacy data
●
    MySQL
    ●
        Our static data
MS SQL Server
●
    Legacy system
    ●
        Clubs
    ●
        Players
    ●
        Leagues


             WE CANNOT AVOID USING IT!
MySQL
●
    Static data
    ●
        Clubs
    ●
        Players
    ●
        Leagues
    ●
        Match Engine definitions
    ●
        Other static parameters...
MongoDB
●
    User data
    ●
        User league
        –   Each user has his own league
    ●
        User team and players
    ●
        User data
        –   Balance
        –   Mailbox
        –   Purchased items
SQL Alchemy
●
    ORM to work with SQL databases
●
    Describe MySQL DB as classes (declarative)
●
    Highly related to SQL
●
    Can describe complex and custom queries and
    relationships
●
    Low level
●
    Conection with legacy system using Soup to
    autodiscover schema
Definition of our own MySQL DB
Base = declarative_base()                        class Role(Base, BaseHelper):
class BaseHelper(object):                          ''' Roles a player can take '''
  @classmethod                                     __tablename__ = 'roles'
  def all(cls):                                    metadata = meta.metadata
    '''Return a Query of all'''
    return meta.Session.query(cls)                 name = sa.Column(sa.types.String(5),
                                                              primary_key=True, nullable=False)
  @classmethod                                     full_name = sa.Column(sa.types.String(25))
  def one_by(cls, **kwargs):                       description = sa.Column(sa.types.String(50))
    return cls.all().filter_by(**kwargs).one()
                                                   def __repr__(self):
  def save(self):                                    return '<{0}>'.format(self.name)
    ''' Save method, like in Django ORM'''
    meta.Session.add(self)
    meta.Session.commit()
Connection to MS SQL Server
●
    FreeTDS to be able to connect from Linux
●
    pyodbc to access the conection on the python
    code
●
    Quite painful to make it to work

          BE CAREFUL WITH THE ENCODING!
Connect to database
import pyodbc
import sqlalchemy as sa
from sqlalchemy.ext.sqlsoup import SqlSoup
def connect():
  return pyodbc.connect('DSN=db_dsn;UID=user;PWD=password')
# force to Unicode. The driver should be configured to UTF-8 mode
engine = sa.create_engine('mssql://', creator=connect,
                           convert_unicode=True)
connection = engine.connect()
# use Soup
meta = MetaData()
meta.bind = connection
db = SqlSoup(meta)
You still have to define the
              relationships!
# tblPerson
db.tblPerson.relate('skin_color', db.tblColour,
                     primaryjoin=db.tblColour.ColourID == db.tblPerson.SkinColourID)
db.tblPerson.relate('hair_color', db.tblColour,
                     primaryjoin=db.tblColour.ColourID == db.tblPerson.HairColourID)
db.tblPerson.relate('nationality_areas', db.tblArea,
                 primaryjoin=db.tblPerson.PersonID == db.tblPersonCountry.PersonID,
                 secondary=db.tblPersonCountry._table,
                 secondaryjoin=db.tblPersonCountry.AreaID == db.tblArea.AreaID)
...
country_codes = [ area.CountryCode for area in player.Person.nationality_areas]
Cache
●
    SQL Alchemy does not have an easy
    integrated cache system.
    ●
        None I know, at least!
    ●
        There is Beaker, but appears to be quite manual
●
    To cache static data (no changes), some
    information is cached the old way.
    ●
        Read the database at the start-up and keep the
        results on global memory
And now for something completely different
mongoengine
●
    Document Object Mapper for MongoDB and
    Python
●
    Built on top of pymongo
●
    Very similar to Django ORM
Connection to DB
import mongoengine
mongoengine.connect('my_database')



           BE CAREFUL WITH DB NAMES!
     If the DB doesn't exist, it will be created!
Definition of a Collection
import mongoengine
class Team(mongoengine.Document):
 name = mongoengine.StringField(required=True)
 players = mongoengine.ListField(Player)
 meta = {
        'indexes':['name'],
        }
team = Team(name='new')
team.save()
Querying and retrieving from DB
Team.objects # All the objects of the collection
Team.objects.get(name='my_team')
Team.objects.filter(name__startswith='my')
Team.objects.filter(embedded_player__name__startswith='Eric')

                        NO JOINS!
              Search on referenced objects
                will return an empty list!
     Team.objects.filter(referenced_player__name__startswith) = []
Get partial objects


                       User.objects.get(user_id=id)
Time (ms)




                        User.objects.only('name', 'level').get(user_id=id)


            0      5     10    15   20   25    30     35   40   45   50


                # Get all fields
                user.reload()
Careful with default attributes!
>>> import mongoengine
>>> class Items(mongoengine.Document):
...   items =mongoengine.ListField(mongoengine.StringField(),default=['starting'])
>>> i = Items()
>>> i.items.append('new_one')
>>> d = Items()
>>> print d.items
['starting','new_one']


                  # Use instead
                  items = mongoengine.ListField(mongoengine.StringField(),
                                               default=lambda: ['starting'])
EmbededDocument vs Document

    Team           Team




                 Player_id

    Player


                  Player
Embed or reference?
●   Our DB is mostly a big User object (not much non-
    static shared data between users)
●   On MongoDB your object can be as big as 4MiB*
●   Performance compromise:
    ●   Dereference objects has an impact (Everything embedded)
    ●   But retrieve big objects with non-needed data takes time
        (Reference objects not used everytime)
●   You can retrieve only the needed parts on each case,
    but that adds complexity to the code.
    * Our user is about 65Kb
Our case
●   Practically all is embedded in a big User object.
●   Except for the CPU controlled-teams in the same
    league of the user.
●   We'll keep an eye on real data when the game is
    launched.


                   The embedded objects have to be
                   saved from the parent Document.
                          Sometimes is tricky.
            Careful with modifying the data and not saving it
Other details
●
    As each player has lots of stats, instead of
    storing each one with a name (DictField), we
    order them and assign them slots on a list
●
    Pymongo 1.9 broke compatibility with
    mongoengine 0.3 Current branch 0.4 working
    on that, but not official release yet
sharding
      mongod    mongod    mongod

      mongod    mongod    mongod

      mongod    mongod    mongod

       shard     shard    shard




C1 mongod       mongos


C2 mongod
Thanks for your attention!

  Questions?

More Related Content

What's hot

Symfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMSymfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODM
Jonathan Wage
 
Designing a JavaFX Mobile application
Designing a JavaFX Mobile applicationDesigning a JavaFX Mobile application
Designing a JavaFX Mobile application
Fabrizio Giudici
 
Java Development with MongoDB
Java Development with MongoDBJava Development with MongoDB
Java Development with MongoDB
Scott Hernandez
 

What's hot (20)

Building node.js applications with Database Jones
Building node.js applications with Database JonesBuilding node.js applications with Database Jones
Building node.js applications with Database Jones
 
Doctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document MapperDoctrine MongoDB Object Document Mapper
Doctrine MongoDB Object Document Mapper
 
Sequelize
SequelizeSequelize
Sequelize
 
Symfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODMSymfony Day 2010 Doctrine MongoDB ODM
Symfony Day 2010 Doctrine MongoDB ODM
 
Designing a JavaFX Mobile application
Designing a JavaFX Mobile applicationDesigning a JavaFX Mobile application
Designing a JavaFX Mobile application
 
Symfony2 from the Trenches
Symfony2 from the TrenchesSymfony2 from the Trenches
Symfony2 from the Trenches
 
My sql tutorial-oscon-2012
My sql tutorial-oscon-2012My sql tutorial-oscon-2012
My sql tutorial-oscon-2012
 
Intro to MongoDB and datamodeling
Intro to MongoDB and datamodeling Intro to MongoDB and datamodeling
Intro to MongoDB and datamodeling
 
Windows 8 JavaScript (Wonderland)
Windows 8 JavaScript (Wonderland)Windows 8 JavaScript (Wonderland)
Windows 8 JavaScript (Wonderland)
 
Mule esb – connecting to ms sql db
Mule esb – connecting to ms sql dbMule esb – connecting to ms sql db
Mule esb – connecting to ms sql db
 
2012-08-29 - NoSQL Bootcamp (Redis, RavenDB & MongoDB für .NET Entwickler)
2012-08-29 - NoSQL Bootcamp (Redis, RavenDB & MongoDB für .NET Entwickler)2012-08-29 - NoSQL Bootcamp (Redis, RavenDB & MongoDB für .NET Entwickler)
2012-08-29 - NoSQL Bootcamp (Redis, RavenDB & MongoDB für .NET Entwickler)
 
Developing for Node.JS with MySQL and NoSQL
Developing for Node.JS with MySQL and NoSQLDeveloping for Node.JS with MySQL and NoSQL
Developing for Node.JS with MySQL and NoSQL
 
iOSDevCamp 2011 Core Data
iOSDevCamp 2011 Core DataiOSDevCamp 2011 Core Data
iOSDevCamp 2011 Core Data
 
Introduction to jOOQ
Introduction to jOOQIntroduction to jOOQ
Introduction to jOOQ
 
MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know MongoDB + Java - Everything you need to know
MongoDB + Java - Everything you need to know
 
Querydsl fin jug - june 2012
Querydsl   fin jug - june 2012Querydsl   fin jug - june 2012
Querydsl fin jug - june 2012
 
Java Development with MongoDB
Java Development with MongoDBJava Development with MongoDB
Java Development with MongoDB
 
New methods for exploiting ORM injections in Java applications
New methods for exploiting ORM injections in Java applicationsNew methods for exploiting ORM injections in Java applications
New methods for exploiting ORM injections in Java applications
 
MongoDB: Easy Java Persistence with Morphia
MongoDB: Easy Java Persistence with MorphiaMongoDB: Easy Java Persistence with Morphia
MongoDB: Easy Java Persistence with Morphia
 
REST/JSON/CoreData Example Code - A Tour
REST/JSON/CoreData Example Code - A TourREST/JSON/CoreData Example Code - A Tour
REST/JSON/CoreData Example Code - A Tour
 

Similar to Database madness with_mongoengine_and_sql_alchemy

PofEAA and SQLAlchemy
PofEAA and SQLAlchemyPofEAA and SQLAlchemy
PofEAA and SQLAlchemy
Inada Naoki
 
Kicking ass with redis
Kicking ass with redisKicking ass with redis
Kicking ass with redis
Dvir Volk
 
introtomongodb
introtomongodbintrotomongodb
introtomongodb
saikiran
 

Similar to Database madness with_mongoengine_and_sql_alchemy (20)

Slickdemo
SlickdemoSlickdemo
Slickdemo
 
PofEAA and SQLAlchemy
PofEAA and SQLAlchemyPofEAA and SQLAlchemy
PofEAA and SQLAlchemy
 
Kicking ass with redis
Kicking ass with redisKicking ass with redis
Kicking ass with redis
 
Django Multi-DB in Anger
Django Multi-DB in AngerDjango Multi-DB in Anger
Django Multi-DB in Anger
 
introtomongodb
introtomongodbintrotomongodb
introtomongodb
 
MongoDB 3.2 - a giant leap. What’s new?
MongoDB 3.2 - a giant leap. What’s new?MongoDB 3.2 - a giant leap. What’s new?
MongoDB 3.2 - a giant leap. What’s new?
 
Introducing Apache Spark's Data Frames and Dataset APIs workshop series
Introducing Apache Spark's Data Frames and Dataset APIs workshop seriesIntroducing Apache Spark's Data Frames and Dataset APIs workshop series
Introducing Apache Spark's Data Frames and Dataset APIs workshop series
 
Jdbc oracle
Jdbc oracleJdbc oracle
Jdbc oracle
 
Get expertise with mongo db
Get expertise with mongo dbGet expertise with mongo db
Get expertise with mongo db
 
Jdbc Java Programming
Jdbc Java ProgrammingJdbc Java Programming
Jdbc Java Programming
 
Strategies for refactoring and migrating a big old project to be multilingual...
Strategies for refactoring and migrating a big old project to be multilingual...Strategies for refactoring and migrating a big old project to be multilingual...
Strategies for refactoring and migrating a big old project to be multilingual...
 
Working with MongoDB as MySQL DBA
Working with MongoDB as MySQL DBAWorking with MongoDB as MySQL DBA
Working with MongoDB as MySQL DBA
 
Mongodb workshop
Mongodb workshopMongodb workshop
Mongodb workshop
 
MongoDB: Optimising for Performance, Scale & Analytics
MongoDB: Optimising for Performance, Scale & AnalyticsMongoDB: Optimising for Performance, Scale & Analytics
MongoDB: Optimising for Performance, Scale & Analytics
 
NoSQL Infrastructure
NoSQL InfrastructureNoSQL Infrastructure
NoSQL Infrastructure
 
PyGrunn 2017 - Django Performance Unchained - slides
PyGrunn 2017 - Django Performance Unchained - slidesPyGrunn 2017 - Django Performance Unchained - slides
PyGrunn 2017 - Django Performance Unchained - slides
 
MongoDB: Comparing WiredTiger In-Memory Engine to Redis
MongoDB: Comparing WiredTiger In-Memory Engine to RedisMongoDB: Comparing WiredTiger In-Memory Engine to Redis
MongoDB: Comparing WiredTiger In-Memory Engine to Redis
 
Euruko 2009 - DataObjects
Euruko 2009 - DataObjectsEuruko 2009 - DataObjects
Euruko 2009 - DataObjects
 
How to use MongoDB with CakePHP
How to use MongoDB with CakePHPHow to use MongoDB with CakePHP
How to use MongoDB with CakePHP
 
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
 

Recently uploaded

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
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
 

Recently uploaded (20)

WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
Apidays New York 2024 - Accelerating FinTech Innovation by Vasa Krishnan, Fin...
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
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...
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 
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
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Platformless Horizons for Digital Adaptability
Platformless Horizons for Digital AdaptabilityPlatformless Horizons for Digital Adaptability
Platformless Horizons for Digital Adaptability
 
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
 
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdfRising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
Rising Above_ Dubai Floods and the Fortitude of Dubai International Airport.pdf
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
Navigating the Deluge_ Dubai Floods and the Resilience of Dubai International...
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 

Database madness with_mongoengine_and_sql_alchemy

  • 1. Database madness with & SQL Alchemy Jaime Buelta jaime.buelta@gmail.com wrongsideofmemphis.worpress.com
  • 2. A little about the project ● Online football management game ● Each user could get a club and control it ● We will import data about leagues, teams, players, etc from a partner ● As we are very optimistic, we are thinking on lots of players! ● Performance + non-relational data --> NoSQL
  • 3. Pylons application ● Pylons is a “framework of frameworks”, as allow to custom made your own framework ● Very standard MVC structure ● RESTful URLs ● jinja2 for templates ● jQuery for the front end (JavaScript, AJAX)
  • 4. Databases used ● MongoDB ● MS SQL Server ● Legacy data ● MySQL ● Our static data
  • 5. MS SQL Server ● Legacy system ● Clubs ● Players ● Leagues WE CANNOT AVOID USING IT!
  • 6. MySQL ● Static data ● Clubs ● Players ● Leagues ● Match Engine definitions ● Other static parameters...
  • 7. MongoDB ● User data ● User league – Each user has his own league ● User team and players ● User data – Balance – Mailbox – Purchased items
  • 8. SQL Alchemy ● ORM to work with SQL databases ● Describe MySQL DB as classes (declarative) ● Highly related to SQL ● Can describe complex and custom queries and relationships ● Low level ● Conection with legacy system using Soup to autodiscover schema
  • 9. Definition of our own MySQL DB Base = declarative_base() class Role(Base, BaseHelper): class BaseHelper(object): ''' Roles a player can take ''' @classmethod __tablename__ = 'roles' def all(cls): metadata = meta.metadata '''Return a Query of all''' return meta.Session.query(cls) name = sa.Column(sa.types.String(5), primary_key=True, nullable=False) @classmethod full_name = sa.Column(sa.types.String(25)) def one_by(cls, **kwargs): description = sa.Column(sa.types.String(50)) return cls.all().filter_by(**kwargs).one() def __repr__(self): def save(self): return '<{0}>'.format(self.name) ''' Save method, like in Django ORM''' meta.Session.add(self) meta.Session.commit()
  • 10. Connection to MS SQL Server ● FreeTDS to be able to connect from Linux ● pyodbc to access the conection on the python code ● Quite painful to make it to work BE CAREFUL WITH THE ENCODING!
  • 11. Connect to database import pyodbc import sqlalchemy as sa from sqlalchemy.ext.sqlsoup import SqlSoup def connect(): return pyodbc.connect('DSN=db_dsn;UID=user;PWD=password') # force to Unicode. The driver should be configured to UTF-8 mode engine = sa.create_engine('mssql://', creator=connect, convert_unicode=True) connection = engine.connect() # use Soup meta = MetaData() meta.bind = connection db = SqlSoup(meta)
  • 12. You still have to define the relationships! # tblPerson db.tblPerson.relate('skin_color', db.tblColour, primaryjoin=db.tblColour.ColourID == db.tblPerson.SkinColourID) db.tblPerson.relate('hair_color', db.tblColour, primaryjoin=db.tblColour.ColourID == db.tblPerson.HairColourID) db.tblPerson.relate('nationality_areas', db.tblArea, primaryjoin=db.tblPerson.PersonID == db.tblPersonCountry.PersonID, secondary=db.tblPersonCountry._table, secondaryjoin=db.tblPersonCountry.AreaID == db.tblArea.AreaID) ... country_codes = [ area.CountryCode for area in player.Person.nationality_areas]
  • 13. Cache ● SQL Alchemy does not have an easy integrated cache system. ● None I know, at least! ● There is Beaker, but appears to be quite manual ● To cache static data (no changes), some information is cached the old way. ● Read the database at the start-up and keep the results on global memory
  • 14. And now for something completely different
  • 15. mongoengine ● Document Object Mapper for MongoDB and Python ● Built on top of pymongo ● Very similar to Django ORM
  • 16. Connection to DB import mongoengine mongoengine.connect('my_database') BE CAREFUL WITH DB NAMES! If the DB doesn't exist, it will be created!
  • 17. Definition of a Collection import mongoengine class Team(mongoengine.Document): name = mongoengine.StringField(required=True) players = mongoengine.ListField(Player) meta = { 'indexes':['name'], } team = Team(name='new') team.save()
  • 18. Querying and retrieving from DB Team.objects # All the objects of the collection Team.objects.get(name='my_team') Team.objects.filter(name__startswith='my') Team.objects.filter(embedded_player__name__startswith='Eric') NO JOINS! Search on referenced objects will return an empty list! Team.objects.filter(referenced_player__name__startswith) = []
  • 19. Get partial objects User.objects.get(user_id=id) Time (ms) User.objects.only('name', 'level').get(user_id=id) 0 5 10 15 20 25 30 35 40 45 50 # Get all fields user.reload()
  • 20. Careful with default attributes! >>> import mongoengine >>> class Items(mongoengine.Document): ... items =mongoengine.ListField(mongoengine.StringField(),default=['starting']) >>> i = Items() >>> i.items.append('new_one') >>> d = Items() >>> print d.items ['starting','new_one'] # Use instead items = mongoengine.ListField(mongoengine.StringField(), default=lambda: ['starting'])
  • 21. EmbededDocument vs Document Team Team Player_id Player Player
  • 22. Embed or reference? ● Our DB is mostly a big User object (not much non- static shared data between users) ● On MongoDB your object can be as big as 4MiB* ● Performance compromise: ● Dereference objects has an impact (Everything embedded) ● But retrieve big objects with non-needed data takes time (Reference objects not used everytime) ● You can retrieve only the needed parts on each case, but that adds complexity to the code. * Our user is about 65Kb
  • 23. Our case ● Practically all is embedded in a big User object. ● Except for the CPU controlled-teams in the same league of the user. ● We'll keep an eye on real data when the game is launched. The embedded objects have to be saved from the parent Document. Sometimes is tricky. Careful with modifying the data and not saving it
  • 24. Other details ● As each player has lots of stats, instead of storing each one with a name (DictField), we order them and assign them slots on a list ● Pymongo 1.9 broke compatibility with mongoengine 0.3 Current branch 0.4 working on that, but not official release yet
  • 25. sharding mongod mongod mongod mongod mongod mongod mongod mongod mongod shard shard shard C1 mongod mongos C2 mongod
  • 26. Thanks for your attention! Questions?