SlideShare una empresa de Scribd logo
1 de 73
Descargar para leer sin conexión
Python and MySQL
Ted Leung
Sun Microsystems
Python-DB
 In the beginning there was the DB-API
 PEP-249
MySQLdb
 MySQLdb written in Python
 _mysql written in C and is MySQL specific
import MySQLdb

conn = MySQLdb.connect(
    host = 'localhost',
    user = 'twl',      Text
                         Text
                           Text
    passwd='pass',             Text
    db='flickrmgr'
)
c = conn.cursor()
c.execute(quot;quot;quot;SELECT * from curator_photoquot;quot;quot;)

# read one row
pprint(c.fetchone())

# read all the rows
pprint(c.fetchall())


((3L,
  3422686825L,
  quot;OPG Toymaker's Doll 2009quot;,
  2L,
  'http://farm4.static.flickr.com/
3377/3422686825_fd57ea30e7.jpg',
  datetime.datetime(2009, 4, 8, 1, 21, 44)),
 (4L,
  3422685683L,
  quot;OPG Toymaker's Doll 2009quot;,
  2L,
  'http://farm4.static.flickr.com/
3608/3422685683_4d16829c19.jpg',
  datetime.datetime(2009, 4, 8, 1, 20, 54)),
dc = conn.cursor(MySQLdb.cursors.DictCursor)
dc.execute(quot;quot;quot;SELECT * from curator_photoquot;quot;quot;)

pprint(dc.fetchmany(5))



({'flickr_id': 2147483647L,
  'id': 2L,
  'pub_date': datetime.datetime(2009, 4, 8, 1, 21, 44),
  'title': quot;OPG Toymaker's Doll 2009quot;,
  'url': 'http://farm4.static.flickr.com/
3377/3422686825_fd57ea30e7.jpg',
  'user_id': 2L},
 {'flickr_id': 3422686825L,
  'id': 3L,
  'pub_date': datetime.datetime(2009, 4, 8, 1, 21, 44),
  'title': quot;OPG Toymaker's Doll 2009quot;,
  'url': 'http://farm4.static.flickr.com/
3377/3422686825_fd57ea30e7.jpg',
  'user_id': 2L})
c.execute(
    quot;quot;quot;SELECT * from curator_photo WHERE id < %squot;quot;quot;,
    (50,))

pprint(c.fetchall())
c.execute(
    quot;quot;quot;INSERT INTO curator_user (flickr_id, name) VALUES
(%s, %s)quot;quot;quot;,
    (quot;000quot;, quot;No Userquot;)
)

conn.commit()
Django
 Leading web application framework
 Lots of people coming to Python via Django today
 Model-View-Controller
 Command line management scripts
 It’s own Rails-like ORM
 Based on the Active Record pattern
Active Record Pattern
 Database table is wrapped in a class
 Each class instance is a row in the table
 Relationships expressd as foreign key constraints
DATABASE_ENGINE = 'mysql'
DATABASE_NAME = 'flickrmgr'
DATABASE_USER = 'twl'
DATABASE_PASSWORD = 'pass'
from django.db import models

class User(models.Model):
    flickr_id = models.TextField()
    name = models.TextField()

    def __unicode__(self):
        return self.name

class Group(models.Model):
    flickr_id = models.TextField()
    name = models.TextField()
    throttle_count = models.IntegerField()
    throttle_mode = models.TextField()
    throttle_remaining = models.IntegerField()

    def __unicode__(self):
        return self.name
class Photo(models.Model):
    flickr_id = models.IntegerField()
    title = models.TextField()
    user = models.ForeignKey(User)
    groups = models.ManyToManyField(Group)
    url = models.URLField()
    pub_date = models.DateTimeField()

   def __unicode__(self):
       return self.title
from curator.models import Photo
from datetime import datetime

Photo.objects.all()
Photo.objects.filter(title__contains='PyCon')

Photo.objects.filter(title__contains='PyCon').exclude(
    pub_date__lte=datetime(2009,4,1))

Photo.objects.filter(title__contains='PyCon').exclude(
    pub_date__lte=datetime(2009,4,1))[2:4]
from django.contrib import admin

class PhotoAdmin(admin.ModelAdmin):
    pass

class GroupAdmin(admin.ModelAdmin):
    pass

class UserAdmin(admin.ModelAdmin):
    pass


admin.site.register(Group, GroupAdmin)
admin.site.register(Photo, PhotoAdmin)
admin.site.register(User, UserAdmin)
def load_from_flickr(request):
    api = API()

    # 51035696189@N01
    twl, created = User.objects.get_or_create(
        flickr_id = '51035696189@N01',
        name = 'Ted Leung'
    )
    if created:
        twl.save()

    photos = api.list_user_info(
        'http://www.flickr.com/photos/twleung')
for photo in photos:
    flickr_id, title, pub_date, url, pools = photo
    new_photo = Photo()
    new_photo.flickr_id = flickr_id
    new_photo.title = title
    new_photo.user = twl
    new_photo.pub_date =
        datetime.fromtimestamp(int(pub_date))
    new_photo.url = url
    new_photo.save()
# do pools
for pool in pools:
    new_pool, created=Group.objects.get_or_create(
        flickr_id = pool[0],
        name = pool[1],
        throttle_count = pool[2],
        throttle_mode = pool[3],
        throttle_remaining = pool[4]
    )
    new_photo.groups.add(new_pool)
    if created:
        new_pool.save()
output = '''
<html>
  <head>
    <title>Bulk loading from Flickr</title>
  </head>
  <body>
  </body>
</html>
'''
    return HttpResponse(output)
from django.conf.urls.defaults import *

from curator.models import User, Group, Photo
from curator.views import load_from_flickr

photo_info_dict = {
    'queryset': Photo.objects.all(),
    'date_field': 'pub_date',
}

urlpatterns = patterns(
    '',
    (r'^$',
     'django.views.generic.date_based.archive_index',
     photo_info_dict),
    (r'^load/$',
     load_from_flickr),
)
Transactions
 Commit on save or delete
 Commit at HTTP request/response boundaries
 commit_manually decorator
Connection Pooling
 Important as systems scale up
 No framework wide solution yet
Migration
 South
 Integrates with manage.py
 Can automatically migrate models
../bin/django startmigration curator --initial

Creating migrations directory at '/Users/twl/work/
mysql-2009/django/flickrmgr/curator/migrations'...

Creating __init__.py in '/Users/twl/work/mysql-2009/
django/flickrmgr/curator/migrations'...
 + Added model 'curator.Photo'
 + Added model 'curator.Group'
 + Added model 'curator.User'
 + Added field 'curator.Photo.groups'
Created 0001_initial.py.
class Photo(models.Model):
    flickr_id = models.IntegerField()
    title = models.TextField()
    user = models.ForeignKey(User)
    groups = models.ManyToManyField(Group)
    url = models.URLField()
    pub_date = models.DateTimeField()
    visible = models.BooleanField()
../bin/django startmigration curator add_visible --auto
 + Added field 'curator.photo.visible'
Created 0002_add_visible.py.
from south.db import db
from django.db import models
from curator.models import *

class Migration:
    def forwards(self, orm):
        # Adding field 'Photo.visible'
        db.add_column('curator_photo', 'visible',
                       models.BooleanField())

    def backwards(self, orm):
        # Deleting field 'Photo.visible'
        db.delete_column('curator_photo', 'visible')
SQLObject
 ORM using Active Record pattern
 Tight coupling to Python classes
 Used in TurboGears 1
connection_string='mysql://twl:pass@localhost/sqlobject'

connection=connectionForURI(connection_string)

sqlhub.processConnection = connection

try:
    User.createTable(ifNotExists=True)
    Photo.createTable(ifNotExists=True)
    FlickrGroup.createTable(ifNotExists=True)
except dberrors.OperationalError, oe:
    print oe
class User(SQLObject):
    flickr_id = StringCol()
    name = StringCol()

class Photo(SQLObject):
    flickr_id = StringCol()
    title = StringCol()
    user = ForeignKey('User')
    groups = RelatedJoin('FlickrGroup')
    url = StringCol()
    pub_date = DateTimeCol()

class FlickrGroup(SQLObject):
    flickr_id = StringCol()
    name = StringCol()
    throttle_count = IntCol()
    throttle_mode = StringCol()
    throttle_remaining = IntCol()
    photos = RelatedJoin('Photo')
pycon_photos =
    list(Photo.select(Photo.q.title.contains('PyCon')))

pprint(pycon_photos)

pycon_apr_photos =
list(Photo.select(AND(Photo.q.title.contains('PyCon'),
                      Photo.q.pub_date > datetime(2009,4,1)
                      )))

pprint(pycon_apr_photos)
api = API()

twl = User(
    flickr_id = '51035696189@N01',
    name = 'Ted Leung'
)

photos = api.list_user_info(
    'http://www.flickr.com/photos/twleung')
for photo in photos:
    print photo
    flickr_id, title, pub_date, url, pools = photo
    new_photo = Photo(
        flickr_id = flickr_id,
        title = title,
        user = twl,
        pub_date = datetime.fromtimestamp(int(pub_date)),
        url = url
    )
# do pools
for pool in pools:
    new_pool =
        list(FlickrGroup.select(
            FlickrGroup.q.flickr_id == pool[0]))
    if len(new_pool) > 0:
        new_pool = new_pool[0]
    else:
        new_pool = None
    if not new_pool:
        new_pool = FlickrGroup(
            flickr_id = pool[0],
            name = pool[1],
            throttle_count = pool[2],
            throttle_mode = pool[3],
            throttle_remaining = pool[4]
        )

    new_photo.addFlickrGroup(new_pool)
Transactions
txn = connection.transaction()

p = Photo.get(1, txn)
p.title = ‘updated photo’

txn.commit()
Connection Pooling
 Connection pooling is built in and on by default
sqlmeta
class Photo(SQLObject):
    class sqlmeta:
        lazyUpdate = True
        cacheValues = False

    flickr_id = StringCol()
    title = StringCol()
    user = ForeignKey('User')
    groups = RelatedJoin('FlickrGroup')
    url = StringCol()
    pub_date = DateTimeCol()
Events
from sqlobject.events import listen
from sqlobject.events RowUpdateSignal, RowCreatedSignal


def update_listener(instance, kwargs):
    kwargs['pub_date'] = datetime.datetime.now()

def created_listener(kwargs, post_funcs):
    print “created photo %s” % (kwargs[‘title’])

listen(update_listener, Photo, RowUpdateSignal)
listen(created_listener, Photo, RowCreatedSignal)
SQLAlchemy
 Python’s answer to Hibernate
 Low level SQL manipulations
 High Level ORM
 Used in TurboGears 2
Low Level SQL
from sqlalchemy   import create_engine
from sqlalchemy   import Table, Column, Integer, String,
Text, DateTime,   MetaData, ForeignKey
from sqlalchemy   import select

engine = create_engine(
    'mysql://twl:pass@localhost/sqlobject',echo=True)

metadata = MetaData()
users_table = Table('user', metadata,
              Column('id', Integer, primary_key=True),
              Column('flickr_id', Text),
              Column('name', Text)
              )

groups_table = Table('group', metadata,
               Column('id', Integer, primary_key=True),
               Column('flickr_id', Text),
               Column('name', Text),
               Column('throttle_count', Integer),
               Column('throttle_mode', Text),
               Column('throttle_remaining', Integer)
               )

photos_table = Table('photo', metadata,
               Column('id', Integer, primary_key=True),
               Column('flickr_id', Text),
               Column('title', Text),
               Column('user_id', Integer,
                      ForeignKey(‘user.id’)),
               Column('url', Text),
               Column('pub_date', DateTime)
               )
metadata.create_all(engine)

conn = engine.connect()

s = select([users_table])
result = conn.execute(s)

for row in result:
    print row

s = select([photos_table],
           photos_table.c.title.contains('PyCon'))

for row in conn.execute(s):
    print row
ins = users.insert().values(name='Thomas Hawk',
                            flickr_id='000')

result = conn.execute(ins)



update =
    users.update().where(
         users.c.name=='Thomas Hawk'
    ).values(
         flickr_id='51035555243@N01'))

result = conn.execute(update)
Transactions
 Regular manual control
 Autocommit - per session
 2PC
Connection Pooling
 Built-in framework
 Done at engine configuration time
Other Low Level SQL features
 Unions and other Set operations
 Scalar Selects
 Correlated Subqueries
 Ordering, Grouping, Offsetting
 Correlated Updates
ORM
 Mapping
 Declarative
class User(object):
    def __repr__(self):
        return quot;<User('%s','%s','%s')>quot; % (
            self.id, self.flickr_id, self.name)

class Group(object):
    def __repr__(self):
        return quot;<Group('%s','%s','%s','%s')>quot; % (
            self.id,
            self.flickr_id,
            self.name,
            self.throttle_remaining
        )

class Photo(object):
    def __repr__(self):
        return quot;<Photo('%s','%s','%s','%s')>quot; % (
            self.id,
            self.flickr_id,
            self.title,
            self.url
        )
metadata = MetaData()

flickr_group_photo = Table(
    'flickr_group_photo', metadata,
    Column('flickr_group_id', Integer,
           ForeignKey('flickr_group.id')),
    Column('photo_id', Integer,
            ForeignKey('photo.id')))
from sqlalchemy.orm import mapper, sessionmaker

engine = create_engine(
    'mysql://twl:pass@localhost/sqlobject')
Session = sessionmaker(bind = engine)
session = Session()

mapper(User, users_table, properties = {
    'photos' : relation(Photo, backref='user')
    })

mapper(Group, groups_table, properties = {
    'photos' : relation(Photo,
                secondary=flickr_group_photo,
                backref='groups')
        })

mapper(Photo, photos_table)

for u in session.query(User):
    print u

for g in session.query(Group):
    print g

for p in session.query(Photo):
    print p
Declarative ORM
from   sqlalchemy.ext.declarative import declarative_base
from   sqlalchemy.orm import sessionmaker
from   sqlalchemy import Column, ForeignKey
from   sqlalchemy import Integer, String, Text, DateTime

Base = declarative_base()

class User(Base):
    __tablename__ = 'user'

    id = Column(Integer, primary_key=True)
    flickr_id = Column(Text)
    name = Column(Text)

    def __repr__(self):
        return quot;<User('%s','%s','%s')>quot; % (
            self.id, self.flickr_id, self.name)
class Group(Base):
    __tablename__ = 'flickr_group'

    id = Column(Integer, primary_key=True)
    flickr_id = Column(Text)
    name = Column(Text)
    throttle_count = Column(Integer)
    throttle_mode = Column(Text)
    throttle_remaining = Column(Integer)

    def __repr__(self):
        return quot;<Group('%s','%s','%s','%s')>quot; % (
            self.id,
            self.flickr_id,
            self.name,
            self.throttle_remaining
        )
class Photo(Base):
    __tablename__ = 'photo'

    id = Column(Integer, primary_key=True)
    flickr_id = Column(Text)
    title = Column(Text)
    user_id = Column(Integer,ForeignKey('user.id'))
    user = relation(User,
        backref=backref('photos', order_by=id))
    groups = relation('Group',
        secondary=flickr_group_photo,
        backref=backref('photos'))
    url = Column(Text)
    pub_date = Column(DateTime)

    def __repr__(self):
        return quot;<Photo('%s','%s','%s','%s')>quot; % (
            self.id,
            self.flickr_id,
            self.title,
            self.url
        )
Session = sessionmaker(bind = engine)
session = Session()

for u in session.query(User):
    print u

for g in session.query(Group):
    print g

for p in session.query(Photo):
    print p
And more
 Advanced mapping
 Multiple table mapping
Elixir
 a simpler way of doing declarative ORM for
  SQLAlchemy
from elixir import *

class User(Entity):
    using_options(tablename = 'user')

    flickr_id = Field(Text)
    name = Field(Text)
    photos = OneToMany('Photo')

    def __repr__(self):
        return quot;<User('%s','%s','%s')>quot; % (
            self.id, self.flickr_id, self.name)
class Group(Entity):
    using_options(tablename = 'flickr_group')

    flickr_id = Field(Text)
    name = Field(Text)
    throttle_count = Field(Integer)
    throttle_mode = Field(Text)
    throttle_remaining = Field(Integer)

    def __repr__(self):
        return quot;<Group('%s','%s','%s','%s')>quot; % (
            self.id,
            self.flickr_id,
            self.name,
            self.throttle_remaining
        )
class Photo(Entity):
    using_options(tablename = 'photo')

    flickr_id = Field(Text)
    title = Field(Text)
    url = Column(Text)
    pub_date = Column(DateTime)
    groups = ManyToMany('Group')
    user = ManyToOne('User')

    def __repr__(self):
        return quot;<Photo('%s','%s','%s','%s')>quot; % (
            self.id,
            self.flickr_id,
            self.title,
            self.url
        )
engine = create_engine(
    'mysql://twl:pass@localhost/sqlobject', echo=True)

Session = sessionmaker(bind = engine)
session = Session()

metadata = MetaData()

metadata.bind='mysql://twl:pass@localhost/sqlobject'
metadata.bind.echo = True

setup_all()

for u in session.query(User):
    print u

for g in session.query(Group):
    print g

for p in session.query(Photo):
    print print
SqlSoup
from sqlalchemy.ext.sqlsoup import SqlSoup

soup = SqlSoup('mysql://twl:pass@localhost/
sqlobject')

soup.photo.all()
soup.photo.order_by(soup.photo.title).all()


[MappedPhoto(id=71L,flickr_id='3286255071',title='',
user_id=1L,url='http://farm4.static.flickr.com/
3249/3286255071_ff168f220b.jpg',pub_date=datetime.da
tetime(2009, 2, 16, 20, 47, 56)),

MappedPhoto(id=72L,flickr_id='3287070244',title='',u
ser_id=1L,url='http://farm4.static.flickr.com/
3298/3287070244_87a2a1b3ed.jpg',pub_date=datetime.da
tetime(2009, 2, 16, 20, 47, 22)),

MappedPhoto(id=46L,flickr_id='3395647634',title='And
y Dustman',user_id=1L,url='http://
farm4.static.flickr.com/
3554/3395647634_cc0c9f5a0a.jpg',pub_date=datetime.da
tetime(2009, 3, 29, 9, 7, 34)),

MappedPhoto(id=73L,flickr_id='3277628077',title='Bai
nbridge Island Chinese New Year
2009',user_id=1L,url='http://
farm4.static.flickr.com/
3334/3277628077_78025002f5.jpg',pub_date=datetime.da
tetime(2009, 2, 13, 23, 31, 52)),
Migrations
 sqlalchemy-migrate
 Version control a database
 A repository of upgrade scripts
from sqlalchemy import *
from migrate import *

metadata = MetaData(migrate_engine)

photos_table = Table('photo', metadata,
               Column('id', Integer, primary_key=True),
               Column('flickr_id', Text),
               Column('title', Text),
               Column('user_id', Integer),
               Column('url', Text),
               Column('pub_date', DateTime),
               )

visible_col = Column('visible', Integer)

def upgrade():
    visible_col.create(photos_table)
    assert visible_col is photos_table.c.visible

def downgrade():
    visible_col.drop()
from sqlalchemy import *
from migrate import *

metadata = MetaData(migrate_engine)

photos_table = Table('photo', metadata,
               Column('id', Integer, primary_key=True),
               Column('flickr_id', Text),
               Column('title', Text),
               Column('user_id', Integer),
               Column('url', Text),
               Column('pub_date', DateTime),
               Column('visible', Integer)
               )

col = photos_table.c.visible

def upgrade():
    col.alter(type=Boolean, nullable=False)

def downgrade():
    col.alter(type=Integer, nullable=True)
Migration operations
 Create/Drop a table
 Create/Drop/Alter a column
 Create/Drop index
 Create/Drop primary/foreign key constraints
Summary
 Django for Django
 SQLAlchemy for the rest
Thanks!

 ted.leung@sun.com
 twitter: twleung

Más contenido relacionado

La actualidad más candente

EX-6-Implement Matrix Multiplication with Hadoop Map Reduce.pptx
EX-6-Implement Matrix Multiplication with Hadoop Map Reduce.pptxEX-6-Implement Matrix Multiplication with Hadoop Map Reduce.pptx
EX-6-Implement Matrix Multiplication with Hadoop Map Reduce.pptxvishal choudhary
 
Unsupervised Aspect Based Sentiment Analysis at Scale
Unsupervised Aspect Based Sentiment Analysis at ScaleUnsupervised Aspect Based Sentiment Analysis at Scale
Unsupervised Aspect Based Sentiment Analysis at ScaleAaron (Ari) Bornstein
 
C* Summit EU 2013: Cassandra Made Simple with CQL Drivers and DevCenter
C* Summit EU 2013: Cassandra Made Simple with CQL Drivers and DevCenter C* Summit EU 2013: Cassandra Made Simple with CQL Drivers and DevCenter
C* Summit EU 2013: Cassandra Made Simple with CQL Drivers and DevCenter DataStax Academy
 
Getting Started with Datatsax .Net Driver
Getting Started with Datatsax .Net DriverGetting Started with Datatsax .Net Driver
Getting Started with Datatsax .Net DriverDataStax Academy
 
Hacking the Mesh: Extending Istio with WebAssembly Modules | DevNation Tech Talk
Hacking the Mesh: Extending Istio with WebAssembly Modules | DevNation Tech TalkHacking the Mesh: Extending Istio with WebAssembly Modules | DevNation Tech Talk
Hacking the Mesh: Extending Istio with WebAssembly Modules | DevNation Tech TalkRed Hat Developers
 
Power shell examples_v4
Power shell examples_v4Power shell examples_v4
Power shell examples_v4JoeDinaso
 
exp-7-pig installation.pptx
exp-7-pig installation.pptxexp-7-pig installation.pptx
exp-7-pig installation.pptxvishal choudhary
 
&lt;x> Rails Web App Security Title
&lt;x> Rails Web App Security Title&lt;x> Rails Web App Security Title
&lt;x> Rails Web App Security Title'"><x> '"><x>
 
#5 (Remote Method Invocation)
#5 (Remote Method Invocation)#5 (Remote Method Invocation)
#5 (Remote Method Invocation)Ghadeer AlHasan
 
Java осень 2012 лекция 2
Java осень 2012 лекция 2Java осень 2012 лекция 2
Java осень 2012 лекция 2Technopark
 
Auto theme updater plugin
Auto theme updater pluginAuto theme updater plugin
Auto theme updater pluginSanam Maharjan
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksMongoDB
 
Database Connectivity in PHP
Database Connectivity in PHPDatabase Connectivity in PHP
Database Connectivity in PHPTaha Malampatti
 
Clustering your Application with Hazelcast
Clustering your Application with HazelcastClustering your Application with Hazelcast
Clustering your Application with HazelcastHazelcast
 

La actualidad más candente (20)

EX-6-Implement Matrix Multiplication with Hadoop Map Reduce.pptx
EX-6-Implement Matrix Multiplication with Hadoop Map Reduce.pptxEX-6-Implement Matrix Multiplication with Hadoop Map Reduce.pptx
EX-6-Implement Matrix Multiplication with Hadoop Map Reduce.pptx
 
Unsupervised Aspect Based Sentiment Analysis at Scale
Unsupervised Aspect Based Sentiment Analysis at ScaleUnsupervised Aspect Based Sentiment Analysis at Scale
Unsupervised Aspect Based Sentiment Analysis at Scale
 
C* Summit EU 2013: Cassandra Made Simple with CQL Drivers and DevCenter
C* Summit EU 2013: Cassandra Made Simple with CQL Drivers and DevCenter C* Summit EU 2013: Cassandra Made Simple with CQL Drivers and DevCenter
C* Summit EU 2013: Cassandra Made Simple with CQL Drivers and DevCenter
 
Getting Started with Datatsax .Net Driver
Getting Started with Datatsax .Net DriverGetting Started with Datatsax .Net Driver
Getting Started with Datatsax .Net Driver
 
QB Into the Box 2018
QB Into the Box 2018QB Into the Box 2018
QB Into the Box 2018
 
Hacking the Mesh: Extending Istio with WebAssembly Modules | DevNation Tech Talk
Hacking the Mesh: Extending Istio with WebAssembly Modules | DevNation Tech TalkHacking the Mesh: Extending Istio with WebAssembly Modules | DevNation Tech Talk
Hacking the Mesh: Extending Istio with WebAssembly Modules | DevNation Tech Talk
 
Ex-8-hive.pptx
Ex-8-hive.pptxEx-8-hive.pptx
Ex-8-hive.pptx
 
Power shell examples_v4
Power shell examples_v4Power shell examples_v4
Power shell examples_v4
 
Dapper
DapperDapper
Dapper
 
exp-7-pig installation.pptx
exp-7-pig installation.pptxexp-7-pig installation.pptx
exp-7-pig installation.pptx
 
&lt;x> Rails Web App Security Title
&lt;x> Rails Web App Security Title&lt;x> Rails Web App Security Title
&lt;x> Rails Web App Security Title
 
#5 (Remote Method Invocation)
#5 (Remote Method Invocation)#5 (Remote Method Invocation)
#5 (Remote Method Invocation)
 
Jdbc
JdbcJdbc
Jdbc
 
Java осень 2012 лекция 2
Java осень 2012 лекция 2Java осень 2012 лекция 2
Java осень 2012 лекция 2
 
BD-zero lecture.pptx
BD-zero lecture.pptxBD-zero lecture.pptx
BD-zero lecture.pptx
 
Auto theme updater plugin
Auto theme updater pluginAuto theme updater plugin
Auto theme updater plugin
 
Fun Teaching MongoDB New Tricks
Fun Teaching MongoDB New TricksFun Teaching MongoDB New Tricks
Fun Teaching MongoDB New Tricks
 
Introduction to php database connectivity
Introduction to php  database connectivityIntroduction to php  database connectivity
Introduction to php database connectivity
 
Database Connectivity in PHP
Database Connectivity in PHPDatabase Connectivity in PHP
Database Connectivity in PHP
 
Clustering your Application with Hazelcast
Clustering your Application with HazelcastClustering your Application with Hazelcast
Clustering your Application with Hazelcast
 

Destacado

Installing MySQL for Python
Installing MySQL for PythonInstalling MySQL for Python
Installing MySQL for PythonSiva Arunachalam
 
Rethink db with Python
Rethink db with PythonRethink db with Python
Rethink db with PythonPrabhu Raghav
 
Www Kitebird Com Articles Pydbapi Html Toc 1
Www Kitebird Com Articles Pydbapi Html Toc 1Www Kitebird Com Articles Pydbapi Html Toc 1
Www Kitebird Com Articles Pydbapi Html Toc 1AkramWaseem
 
Succumbing to the Python in Financial Markets
Succumbing to the Python in Financial MarketsSuccumbing to the Python in Financial Markets
Succumbing to the Python in Financial Marketsdcerezo
 
"PostgreSQL and Python" Lightning Talk @EuroPython2014
"PostgreSQL and Python" Lightning Talk @EuroPython2014"PostgreSQL and Python" Lightning Talk @EuroPython2014
"PostgreSQL and Python" Lightning Talk @EuroPython2014Henning Jacobs
 
Scaling mysql with python (and Docker).
Scaling mysql with python (and Docker).Scaling mysql with python (and Docker).
Scaling mysql with python (and Docker).Roberto Polli
 
Relational Database Access with Python ‘sans’ ORM
Relational Database Access with Python ‘sans’ ORM  Relational Database Access with Python ‘sans’ ORM
Relational Database Access with Python ‘sans’ ORM Mark Rees
 
Python for Derivative Analytics
Python for Derivative AnalyticsPython for Derivative Analytics
Python for Derivative AnalyticsAlicia G
 
Programming with Python and PostgreSQL
Programming with Python and PostgreSQLProgramming with Python and PostgreSQL
Programming with Python and PostgreSQLPeter Eisentraut
 
Python Utilities for Managing MySQL Databases
Python Utilities for Managing MySQL DatabasesPython Utilities for Managing MySQL Databases
Python Utilities for Managing MySQL DatabasesMats Kindahl
 
PostgreSQLとPythonとSQL
PostgreSQLとPythonとSQLPostgreSQLとPythonとSQL
PostgreSQLとPythonとSQLSatoshi Yamada
 
Python for Big Data Analytics
Python for Big Data AnalyticsPython for Big Data Analytics
Python for Big Data AnalyticsEdureka!
 
Python for Big Data Analytics
Python for Big Data AnalyticsPython for Big Data Analytics
Python for Big Data AnalyticsEdureka!
 
Ten Reasons Why You Should Prefer PostgreSQL to MySQL
Ten Reasons Why You Should Prefer PostgreSQL to MySQLTen Reasons Why You Should Prefer PostgreSQL to MySQL
Ten Reasons Why You Should Prefer PostgreSQL to MySQLanandology
 
Python PPT
Python PPTPython PPT
Python PPTEdureka!
 
Git 101 - Crash Course in Version Control using Git
Git 101 - Crash Course in Version Control using GitGit 101 - Crash Course in Version Control using Git
Git 101 - Crash Course in Version Control using GitGeoff Hoffman
 
Introduction to Git/Github - A beginner's guide
Introduction to Git/Github - A beginner's guideIntroduction to Git/Github - A beginner's guide
Introduction to Git/Github - A beginner's guideRohit Arora
 
Orchestrating Docker containers at scale
Orchestrating Docker containers at scaleOrchestrating Docker containers at scale
Orchestrating Docker containers at scaleMaciej Lasyk
 
Git 101: Git and GitHub for Beginners
Git 101: Git and GitHub for Beginners Git 101: Git and GitHub for Beginners
Git 101: Git and GitHub for Beginners HubSpot
 

Destacado (20)

Installing MySQL for Python
Installing MySQL for PythonInstalling MySQL for Python
Installing MySQL for Python
 
Rethink db with Python
Rethink db with PythonRethink db with Python
Rethink db with Python
 
Www Kitebird Com Articles Pydbapi Html Toc 1
Www Kitebird Com Articles Pydbapi Html Toc 1Www Kitebird Com Articles Pydbapi Html Toc 1
Www Kitebird Com Articles Pydbapi Html Toc 1
 
Succumbing to the Python in Financial Markets
Succumbing to the Python in Financial MarketsSuccumbing to the Python in Financial Markets
Succumbing to the Python in Financial Markets
 
"PostgreSQL and Python" Lightning Talk @EuroPython2014
"PostgreSQL and Python" Lightning Talk @EuroPython2014"PostgreSQL and Python" Lightning Talk @EuroPython2014
"PostgreSQL and Python" Lightning Talk @EuroPython2014
 
Scaling mysql with python (and Docker).
Scaling mysql with python (and Docker).Scaling mysql with python (and Docker).
Scaling mysql with python (and Docker).
 
Relational Database Access with Python ‘sans’ ORM
Relational Database Access with Python ‘sans’ ORM  Relational Database Access with Python ‘sans’ ORM
Relational Database Access with Python ‘sans’ ORM
 
Python for Derivative Analytics
Python for Derivative AnalyticsPython for Derivative Analytics
Python for Derivative Analytics
 
Programming with Python and PostgreSQL
Programming with Python and PostgreSQLProgramming with Python and PostgreSQL
Programming with Python and PostgreSQL
 
Python Utilities for Managing MySQL Databases
Python Utilities for Managing MySQL DatabasesPython Utilities for Managing MySQL Databases
Python Utilities for Managing MySQL Databases
 
PostgreSQLとPythonとSQL
PostgreSQLとPythonとSQLPostgreSQLとPythonとSQL
PostgreSQLとPythonとSQL
 
Python for Big Data Analytics
Python for Big Data AnalyticsPython for Big Data Analytics
Python for Big Data Analytics
 
Python for Big Data Analytics
Python for Big Data AnalyticsPython for Big Data Analytics
Python for Big Data Analytics
 
Ten Reasons Why You Should Prefer PostgreSQL to MySQL
Ten Reasons Why You Should Prefer PostgreSQL to MySQLTen Reasons Why You Should Prefer PostgreSQL to MySQL
Ten Reasons Why You Should Prefer PostgreSQL to MySQL
 
Python PPT
Python PPTPython PPT
Python PPT
 
Git 101 - Crash Course in Version Control using Git
Git 101 - Crash Course in Version Control using GitGit 101 - Crash Course in Version Control using Git
Git 101 - Crash Course in Version Control using Git
 
Introduction to Git/Github - A beginner's guide
Introduction to Git/Github - A beginner's guideIntroduction to Git/Github - A beginner's guide
Introduction to Git/Github - A beginner's guide
 
Orchestrating Docker containers at scale
Orchestrating Docker containers at scaleOrchestrating Docker containers at scale
Orchestrating Docker containers at scale
 
Git 101: Git and GitHub for Beginners
Git 101: Git and GitHub for Beginners Git 101: Git and GitHub for Beginners
Git 101: Git and GitHub for Beginners
 
Python Presentation
Python PresentationPython Presentation
Python Presentation
 

Similar a MySQL User Conference 2009: Python and MySQL

OSCON 2005: Build Your Own Chandler Parcel
OSCON 2005: Build Your Own Chandler ParcelOSCON 2005: Build Your Own Chandler Parcel
OSCON 2005: Build Your Own Chandler ParcelTed Leung
 
Javascript Application Architecture with Backbone.JS
Javascript Application Architecture with Backbone.JSJavascript Application Architecture with Backbone.JS
Javascript Application Architecture with Backbone.JSMin Ming Lo
 
JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"GeeksLab Odessa
 
Gutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisablesGutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisablesRiad Benguella
 
Protractor framework – how to make stable e2e tests for Angular applications
Protractor framework – how to make stable e2e tests for Angular applicationsProtractor framework – how to make stable e2e tests for Angular applications
Protractor framework – how to make stable e2e tests for Angular applicationsLudmila Nesvitiy
 
Lo nuevo de Django 1.7 y 1.8
Lo nuevo de Django 1.7 y 1.8Lo nuevo de Django 1.7 y 1.8
Lo nuevo de Django 1.7 y 1.8pedroburonv
 
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Luka Zakrajšek
 
Breaking the limits_of_page_objects
Breaking the limits_of_page_objectsBreaking the limits_of_page_objects
Breaking the limits_of_page_objectsRobert Bossek
 
Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)Python Ireland
 
Gae Meets Django
Gae Meets DjangoGae Meets Django
Gae Meets Djangofool2nd
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to DjangoJoaquim Rocha
 
Building Cloud-Backed Mobile Apps (MBL402) | AWS re:Invent 2013
Building Cloud-Backed Mobile Apps (MBL402) | AWS re:Invent 2013Building Cloud-Backed Mobile Apps (MBL402) | AWS re:Invent 2013
Building Cloud-Backed Mobile Apps (MBL402) | AWS re:Invent 2013Amazon Web Services
 
Web Components With Rails
Web Components With RailsWeb Components With Rails
Web Components With RailsBoris Nadion
 
Python Development (MongoSF)
Python Development (MongoSF)Python Development (MongoSF)
Python Development (MongoSF)Mike Dirolf
 

Similar a MySQL User Conference 2009: Python and MySQL (20)

OSCON 2005: Build Your Own Chandler Parcel
OSCON 2005: Build Your Own Chandler ParcelOSCON 2005: Build Your Own Chandler Parcel
OSCON 2005: Build Your Own Chandler Parcel
 
Web api's
Web api'sWeb api's
Web api's
 
Javascript Application Architecture with Backbone.JS
Javascript Application Architecture with Backbone.JSJavascript Application Architecture with Backbone.JS
Javascript Application Architecture with Backbone.JS
 
Android workshop
Android workshopAndroid workshop
Android workshop
 
JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"JSLab. Алексей Волков. "React на практике"
JSLab. Алексей Волков. "React на практике"
 
Gutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisablesGutenberg sous le capot, modules réutilisables
Gutenberg sous le capot, modules réutilisables
 
Protractor framework – how to make stable e2e tests for Angular applications
Protractor framework – how to make stable e2e tests for Angular applicationsProtractor framework – how to make stable e2e tests for Angular applications
Protractor framework – how to make stable e2e tests for Angular applications
 
Lo nuevo de Django 1.7 y 1.8
Lo nuevo de Django 1.7 y 1.8Lo nuevo de Django 1.7 y 1.8
Lo nuevo de Django 1.7 y 1.8
 
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)
 
Breaking the limits_of_page_objects
Breaking the limits_of_page_objectsBreaking the limits_of_page_objects
Breaking the limits_of_page_objects
 
Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)Google App Engine in 40 minutes (the absolute essentials)
Google App Engine in 40 minutes (the absolute essentials)
 
From newbie to ...
From newbie to ...From newbie to ...
From newbie to ...
 
Gae Meets Django
Gae Meets DjangoGae Meets Django
Gae Meets Django
 
Backbone Basics with Examples
Backbone Basics with ExamplesBackbone Basics with Examples
Backbone Basics with Examples
 
Django
DjangoDjango
Django
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
Building Cloud-Backed Mobile Apps (MBL402) | AWS re:Invent 2013
Building Cloud-Backed Mobile Apps (MBL402) | AWS re:Invent 2013Building Cloud-Backed Mobile Apps (MBL402) | AWS re:Invent 2013
Building Cloud-Backed Mobile Apps (MBL402) | AWS re:Invent 2013
 
Django
DjangoDjango
Django
 
Web Components With Rails
Web Components With RailsWeb Components With Rails
Web Components With Rails
 
Python Development (MongoSF)
Python Development (MongoSF)Python Development (MongoSF)
Python Development (MongoSF)
 

Más de Ted Leung

DjangoCon 2009 Keynote
DjangoCon 2009 KeynoteDjangoCon 2009 Keynote
DjangoCon 2009 KeynoteTed Leung
 
A Survey of Concurrency Constructs
A Survey of Concurrency ConstructsA Survey of Concurrency Constructs
A Survey of Concurrency ConstructsTed Leung
 
Seeding The Cloud
Seeding The CloudSeeding The Cloud
Seeding The CloudTed Leung
 
Programming Languages For The Cloud
Programming Languages For The CloudProgramming Languages For The Cloud
Programming Languages For The CloudTed Leung
 
PyCon US 2009: Challenges and Opportunities for Python
PyCon US 2009: Challenges and Opportunities for PythonPyCon US 2009: Challenges and Opportunities for Python
PyCon US 2009: Challenges and Opportunities for PythonTed Leung
 
Northwest Python Day 2009
Northwest Python Day 2009Northwest Python Day 2009
Northwest Python Day 2009Ted Leung
 
PyCon UK 2008: Challenges for Dynamic Languages
PyCon UK 2008: Challenges for Dynamic LanguagesPyCon UK 2008: Challenges for Dynamic Languages
PyCon UK 2008: Challenges for Dynamic LanguagesTed Leung
 
OSCON 2008: Open Source Community Antipatterns
OSCON 2008: Open Source Community AntipatternsOSCON 2008: Open Source Community Antipatterns
OSCON 2008: Open Source Community AntipatternsTed Leung
 
OSCON 2007: Open Design, Not By Committee
OSCON 2007: Open Design, Not By CommitteeOSCON 2007: Open Design, Not By Committee
OSCON 2007: Open Design, Not By CommitteeTed Leung
 
Ignite The Web 2007
Ignite The Web 2007Ignite The Web 2007
Ignite The Web 2007Ted Leung
 
ApacheCon US 2007: Open Source Community Antipatterns
ApacheCon US 2007:  Open Source Community AntipatternsApacheCon US 2007:  Open Source Community Antipatterns
ApacheCon US 2007: Open Source Community AntipatternsTed Leung
 
PyCon 2005 PyBlosxom
PyCon 2005 PyBlosxomPyCon 2005 PyBlosxom
PyCon 2005 PyBlosxomTed Leung
 
SeaJUG March 2004 - Groovy
SeaJUG March 2004 - GroovySeaJUG March 2004 - Groovy
SeaJUG March 2004 - GroovyTed Leung
 
OSCON 2004: XML and Apache
OSCON 2004: XML and ApacheOSCON 2004: XML and Apache
OSCON 2004: XML and ApacheTed Leung
 
OSCON 2004: A Developer's Tour of Chandler
OSCON 2004: A Developer's Tour of ChandlerOSCON 2004: A Developer's Tour of Chandler
OSCON 2004: A Developer's Tour of ChandlerTed Leung
 
SeaJUG Dec 2001: Aspect-Oriented Programming with AspectJ
SeaJUG Dec 2001: Aspect-Oriented Programming with AspectJSeaJUG Dec 2001: Aspect-Oriented Programming with AspectJ
SeaJUG Dec 2001: Aspect-Oriented Programming with AspectJTed Leung
 
IQPC Canada XML 2001: How to develop Syntax and XML Schema
IQPC Canada XML 2001: How to develop Syntax and XML SchemaIQPC Canada XML 2001: How to develop Syntax and XML Schema
IQPC Canada XML 2001: How to develop Syntax and XML SchemaTed Leung
 
IQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic Communication
IQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic CommunicationIQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic Communication
IQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic CommunicationTed Leung
 
ApacheCon 2000 Everything you ever wanted to know about XML Parsing
ApacheCon 2000 Everything you ever wanted to know about XML ParsingApacheCon 2000 Everything you ever wanted to know about XML Parsing
ApacheCon 2000 Everything you ever wanted to know about XML ParsingTed Leung
 
SD Forum 1999 XML Lessons Learned
SD Forum 1999 XML Lessons LearnedSD Forum 1999 XML Lessons Learned
SD Forum 1999 XML Lessons LearnedTed Leung
 

Más de Ted Leung (20)

DjangoCon 2009 Keynote
DjangoCon 2009 KeynoteDjangoCon 2009 Keynote
DjangoCon 2009 Keynote
 
A Survey of Concurrency Constructs
A Survey of Concurrency ConstructsA Survey of Concurrency Constructs
A Survey of Concurrency Constructs
 
Seeding The Cloud
Seeding The CloudSeeding The Cloud
Seeding The Cloud
 
Programming Languages For The Cloud
Programming Languages For The CloudProgramming Languages For The Cloud
Programming Languages For The Cloud
 
PyCon US 2009: Challenges and Opportunities for Python
PyCon US 2009: Challenges and Opportunities for PythonPyCon US 2009: Challenges and Opportunities for Python
PyCon US 2009: Challenges and Opportunities for Python
 
Northwest Python Day 2009
Northwest Python Day 2009Northwest Python Day 2009
Northwest Python Day 2009
 
PyCon UK 2008: Challenges for Dynamic Languages
PyCon UK 2008: Challenges for Dynamic LanguagesPyCon UK 2008: Challenges for Dynamic Languages
PyCon UK 2008: Challenges for Dynamic Languages
 
OSCON 2008: Open Source Community Antipatterns
OSCON 2008: Open Source Community AntipatternsOSCON 2008: Open Source Community Antipatterns
OSCON 2008: Open Source Community Antipatterns
 
OSCON 2007: Open Design, Not By Committee
OSCON 2007: Open Design, Not By CommitteeOSCON 2007: Open Design, Not By Committee
OSCON 2007: Open Design, Not By Committee
 
Ignite The Web 2007
Ignite The Web 2007Ignite The Web 2007
Ignite The Web 2007
 
ApacheCon US 2007: Open Source Community Antipatterns
ApacheCon US 2007:  Open Source Community AntipatternsApacheCon US 2007:  Open Source Community Antipatterns
ApacheCon US 2007: Open Source Community Antipatterns
 
PyCon 2005 PyBlosxom
PyCon 2005 PyBlosxomPyCon 2005 PyBlosxom
PyCon 2005 PyBlosxom
 
SeaJUG March 2004 - Groovy
SeaJUG March 2004 - GroovySeaJUG March 2004 - Groovy
SeaJUG March 2004 - Groovy
 
OSCON 2004: XML and Apache
OSCON 2004: XML and ApacheOSCON 2004: XML and Apache
OSCON 2004: XML and Apache
 
OSCON 2004: A Developer's Tour of Chandler
OSCON 2004: A Developer's Tour of ChandlerOSCON 2004: A Developer's Tour of Chandler
OSCON 2004: A Developer's Tour of Chandler
 
SeaJUG Dec 2001: Aspect-Oriented Programming with AspectJ
SeaJUG Dec 2001: Aspect-Oriented Programming with AspectJSeaJUG Dec 2001: Aspect-Oriented Programming with AspectJ
SeaJUG Dec 2001: Aspect-Oriented Programming with AspectJ
 
IQPC Canada XML 2001: How to develop Syntax and XML Schema
IQPC Canada XML 2001: How to develop Syntax and XML SchemaIQPC Canada XML 2001: How to develop Syntax and XML Schema
IQPC Canada XML 2001: How to develop Syntax and XML Schema
 
IQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic Communication
IQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic CommunicationIQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic Communication
IQPC Canada XML 2001: How to Use XML Parsing to Enhance Electronic Communication
 
ApacheCon 2000 Everything you ever wanted to know about XML Parsing
ApacheCon 2000 Everything you ever wanted to know about XML ParsingApacheCon 2000 Everything you ever wanted to know about XML Parsing
ApacheCon 2000 Everything you ever wanted to know about XML Parsing
 
SD Forum 1999 XML Lessons Learned
SD Forum 1999 XML Lessons LearnedSD Forum 1999 XML Lessons Learned
SD Forum 1999 XML Lessons Learned
 

Último

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsJoaquim Jorge
 
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
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
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...Miguel Araújo
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
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.pdfsudhanshuwaghmare1
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUK Journal
 
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
 
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
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?Antenna Manufacturer Coco
 
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...Drew Madelung
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
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
 

Último (20)

Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
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
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
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...
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
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
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
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
 
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
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
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...
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
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
 

MySQL User Conference 2009: Python and MySQL

  • 1. Python and MySQL Ted Leung Sun Microsystems
  • 2.
  • 3.
  • 4. Python-DB  In the beginning there was the DB-API  PEP-249
  • 5. MySQLdb  MySQLdb written in Python  _mysql written in C and is MySQL specific
  • 6. import MySQLdb conn = MySQLdb.connect( host = 'localhost', user = 'twl', Text Text Text passwd='pass', Text db='flickrmgr' )
  • 7. c = conn.cursor() c.execute(quot;quot;quot;SELECT * from curator_photoquot;quot;quot;) # read one row pprint(c.fetchone()) # read all the rows pprint(c.fetchall()) ((3L, 3422686825L, quot;OPG Toymaker's Doll 2009quot;, 2L, 'http://farm4.static.flickr.com/ 3377/3422686825_fd57ea30e7.jpg', datetime.datetime(2009, 4, 8, 1, 21, 44)), (4L, 3422685683L, quot;OPG Toymaker's Doll 2009quot;, 2L, 'http://farm4.static.flickr.com/ 3608/3422685683_4d16829c19.jpg', datetime.datetime(2009, 4, 8, 1, 20, 54)),
  • 8. dc = conn.cursor(MySQLdb.cursors.DictCursor) dc.execute(quot;quot;quot;SELECT * from curator_photoquot;quot;quot;) pprint(dc.fetchmany(5)) ({'flickr_id': 2147483647L, 'id': 2L, 'pub_date': datetime.datetime(2009, 4, 8, 1, 21, 44), 'title': quot;OPG Toymaker's Doll 2009quot;, 'url': 'http://farm4.static.flickr.com/ 3377/3422686825_fd57ea30e7.jpg', 'user_id': 2L}, {'flickr_id': 3422686825L, 'id': 3L, 'pub_date': datetime.datetime(2009, 4, 8, 1, 21, 44), 'title': quot;OPG Toymaker's Doll 2009quot;, 'url': 'http://farm4.static.flickr.com/ 3377/3422686825_fd57ea30e7.jpg', 'user_id': 2L})
  • 9. c.execute( quot;quot;quot;SELECT * from curator_photo WHERE id < %squot;quot;quot;, (50,)) pprint(c.fetchall())
  • 10. c.execute( quot;quot;quot;INSERT INTO curator_user (flickr_id, name) VALUES (%s, %s)quot;quot;quot;, (quot;000quot;, quot;No Userquot;) ) conn.commit()
  • 11. Django  Leading web application framework  Lots of people coming to Python via Django today  Model-View-Controller  Command line management scripts  It’s own Rails-like ORM  Based on the Active Record pattern
  • 12. Active Record Pattern  Database table is wrapped in a class  Each class instance is a row in the table  Relationships expressd as foreign key constraints
  • 13. DATABASE_ENGINE = 'mysql' DATABASE_NAME = 'flickrmgr' DATABASE_USER = 'twl' DATABASE_PASSWORD = 'pass'
  • 14. from django.db import models class User(models.Model): flickr_id = models.TextField() name = models.TextField() def __unicode__(self): return self.name class Group(models.Model): flickr_id = models.TextField() name = models.TextField() throttle_count = models.IntegerField() throttle_mode = models.TextField() throttle_remaining = models.IntegerField() def __unicode__(self): return self.name
  • 15. class Photo(models.Model): flickr_id = models.IntegerField() title = models.TextField() user = models.ForeignKey(User) groups = models.ManyToManyField(Group) url = models.URLField() pub_date = models.DateTimeField() def __unicode__(self): return self.title
  • 16. from curator.models import Photo from datetime import datetime Photo.objects.all() Photo.objects.filter(title__contains='PyCon') Photo.objects.filter(title__contains='PyCon').exclude( pub_date__lte=datetime(2009,4,1)) Photo.objects.filter(title__contains='PyCon').exclude( pub_date__lte=datetime(2009,4,1))[2:4]
  • 17. from django.contrib import admin class PhotoAdmin(admin.ModelAdmin): pass class GroupAdmin(admin.ModelAdmin): pass class UserAdmin(admin.ModelAdmin): pass admin.site.register(Group, GroupAdmin) admin.site.register(Photo, PhotoAdmin) admin.site.register(User, UserAdmin)
  • 18. def load_from_flickr(request): api = API() # 51035696189@N01 twl, created = User.objects.get_or_create( flickr_id = '51035696189@N01', name = 'Ted Leung' ) if created: twl.save() photos = api.list_user_info( 'http://www.flickr.com/photos/twleung')
  • 19. for photo in photos: flickr_id, title, pub_date, url, pools = photo new_photo = Photo() new_photo.flickr_id = flickr_id new_photo.title = title new_photo.user = twl new_photo.pub_date = datetime.fromtimestamp(int(pub_date)) new_photo.url = url new_photo.save()
  • 20. # do pools for pool in pools: new_pool, created=Group.objects.get_or_create( flickr_id = pool[0], name = pool[1], throttle_count = pool[2], throttle_mode = pool[3], throttle_remaining = pool[4] ) new_photo.groups.add(new_pool) if created: new_pool.save()
  • 21. output = ''' <html> <head> <title>Bulk loading from Flickr</title> </head> <body> </body> </html> ''' return HttpResponse(output)
  • 22. from django.conf.urls.defaults import * from curator.models import User, Group, Photo from curator.views import load_from_flickr photo_info_dict = { 'queryset': Photo.objects.all(), 'date_field': 'pub_date', } urlpatterns = patterns( '', (r'^$', 'django.views.generic.date_based.archive_index', photo_info_dict), (r'^load/$', load_from_flickr), )
  • 23. Transactions  Commit on save or delete  Commit at HTTP request/response boundaries  commit_manually decorator
  • 24. Connection Pooling  Important as systems scale up  No framework wide solution yet
  • 25. Migration  South  Integrates with manage.py  Can automatically migrate models
  • 26. ../bin/django startmigration curator --initial Creating migrations directory at '/Users/twl/work/ mysql-2009/django/flickrmgr/curator/migrations'... Creating __init__.py in '/Users/twl/work/mysql-2009/ django/flickrmgr/curator/migrations'... + Added model 'curator.Photo' + Added model 'curator.Group' + Added model 'curator.User' + Added field 'curator.Photo.groups' Created 0001_initial.py.
  • 27. class Photo(models.Model): flickr_id = models.IntegerField() title = models.TextField() user = models.ForeignKey(User) groups = models.ManyToManyField(Group) url = models.URLField() pub_date = models.DateTimeField() visible = models.BooleanField()
  • 28. ../bin/django startmigration curator add_visible --auto + Added field 'curator.photo.visible' Created 0002_add_visible.py.
  • 29. from south.db import db from django.db import models from curator.models import * class Migration: def forwards(self, orm): # Adding field 'Photo.visible' db.add_column('curator_photo', 'visible', models.BooleanField()) def backwards(self, orm): # Deleting field 'Photo.visible' db.delete_column('curator_photo', 'visible')
  • 30. SQLObject  ORM using Active Record pattern  Tight coupling to Python classes  Used in TurboGears 1
  • 31. connection_string='mysql://twl:pass@localhost/sqlobject' connection=connectionForURI(connection_string) sqlhub.processConnection = connection try: User.createTable(ifNotExists=True) Photo.createTable(ifNotExists=True) FlickrGroup.createTable(ifNotExists=True) except dberrors.OperationalError, oe: print oe
  • 32. class User(SQLObject): flickr_id = StringCol() name = StringCol() class Photo(SQLObject): flickr_id = StringCol() title = StringCol() user = ForeignKey('User') groups = RelatedJoin('FlickrGroup') url = StringCol() pub_date = DateTimeCol() class FlickrGroup(SQLObject): flickr_id = StringCol() name = StringCol() throttle_count = IntCol() throttle_mode = StringCol() throttle_remaining = IntCol() photos = RelatedJoin('Photo')
  • 33. pycon_photos = list(Photo.select(Photo.q.title.contains('PyCon'))) pprint(pycon_photos) pycon_apr_photos = list(Photo.select(AND(Photo.q.title.contains('PyCon'), Photo.q.pub_date > datetime(2009,4,1) ))) pprint(pycon_apr_photos)
  • 34. api = API() twl = User( flickr_id = '51035696189@N01', name = 'Ted Leung' ) photos = api.list_user_info( 'http://www.flickr.com/photos/twleung')
  • 35. for photo in photos: print photo flickr_id, title, pub_date, url, pools = photo new_photo = Photo( flickr_id = flickr_id, title = title, user = twl, pub_date = datetime.fromtimestamp(int(pub_date)), url = url )
  • 36. # do pools for pool in pools: new_pool = list(FlickrGroup.select( FlickrGroup.q.flickr_id == pool[0])) if len(new_pool) > 0: new_pool = new_pool[0] else: new_pool = None if not new_pool: new_pool = FlickrGroup( flickr_id = pool[0], name = pool[1], throttle_count = pool[2], throttle_mode = pool[3], throttle_remaining = pool[4] ) new_photo.addFlickrGroup(new_pool)
  • 37. Transactions txn = connection.transaction() p = Photo.get(1, txn) p.title = ‘updated photo’ txn.commit()
  • 38. Connection Pooling  Connection pooling is built in and on by default
  • 39. sqlmeta class Photo(SQLObject): class sqlmeta: lazyUpdate = True cacheValues = False flickr_id = StringCol() title = StringCol() user = ForeignKey('User') groups = RelatedJoin('FlickrGroup') url = StringCol() pub_date = DateTimeCol()
  • 40. Events from sqlobject.events import listen from sqlobject.events RowUpdateSignal, RowCreatedSignal def update_listener(instance, kwargs): kwargs['pub_date'] = datetime.datetime.now() def created_listener(kwargs, post_funcs): print “created photo %s” % (kwargs[‘title’]) listen(update_listener, Photo, RowUpdateSignal) listen(created_listener, Photo, RowCreatedSignal)
  • 41. SQLAlchemy  Python’s answer to Hibernate  Low level SQL manipulations  High Level ORM  Used in TurboGears 2
  • 43. from sqlalchemy import create_engine from sqlalchemy import Table, Column, Integer, String, Text, DateTime, MetaData, ForeignKey from sqlalchemy import select engine = create_engine( 'mysql://twl:pass@localhost/sqlobject',echo=True) metadata = MetaData()
  • 44. users_table = Table('user', metadata, Column('id', Integer, primary_key=True), Column('flickr_id', Text), Column('name', Text) ) groups_table = Table('group', metadata, Column('id', Integer, primary_key=True), Column('flickr_id', Text), Column('name', Text), Column('throttle_count', Integer), Column('throttle_mode', Text), Column('throttle_remaining', Integer) ) photos_table = Table('photo', metadata, Column('id', Integer, primary_key=True), Column('flickr_id', Text), Column('title', Text), Column('user_id', Integer, ForeignKey(‘user.id’)), Column('url', Text), Column('pub_date', DateTime) )
  • 45. metadata.create_all(engine) conn = engine.connect() s = select([users_table]) result = conn.execute(s) for row in result: print row s = select([photos_table], photos_table.c.title.contains('PyCon')) for row in conn.execute(s): print row
  • 46. ins = users.insert().values(name='Thomas Hawk', flickr_id='000') result = conn.execute(ins) update = users.update().where( users.c.name=='Thomas Hawk' ).values( flickr_id='51035555243@N01')) result = conn.execute(update)
  • 47. Transactions  Regular manual control  Autocommit - per session  2PC
  • 48. Connection Pooling  Built-in framework  Done at engine configuration time
  • 49. Other Low Level SQL features  Unions and other Set operations  Scalar Selects  Correlated Subqueries  Ordering, Grouping, Offsetting  Correlated Updates
  • 51. class User(object): def __repr__(self): return quot;<User('%s','%s','%s')>quot; % ( self.id, self.flickr_id, self.name) class Group(object): def __repr__(self): return quot;<Group('%s','%s','%s','%s')>quot; % ( self.id, self.flickr_id, self.name, self.throttle_remaining ) class Photo(object): def __repr__(self): return quot;<Photo('%s','%s','%s','%s')>quot; % ( self.id, self.flickr_id, self.title, self.url )
  • 52. metadata = MetaData() flickr_group_photo = Table( 'flickr_group_photo', metadata, Column('flickr_group_id', Integer, ForeignKey('flickr_group.id')), Column('photo_id', Integer, ForeignKey('photo.id')))
  • 53. from sqlalchemy.orm import mapper, sessionmaker engine = create_engine( 'mysql://twl:pass@localhost/sqlobject')
  • 54. Session = sessionmaker(bind = engine) session = Session() mapper(User, users_table, properties = { 'photos' : relation(Photo, backref='user') }) mapper(Group, groups_table, properties = { 'photos' : relation(Photo, secondary=flickr_group_photo, backref='groups') }) mapper(Photo, photos_table) for u in session.query(User): print u for g in session.query(Group): print g for p in session.query(Photo): print p
  • 56. from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.orm import sessionmaker from sqlalchemy import Column, ForeignKey from sqlalchemy import Integer, String, Text, DateTime Base = declarative_base() class User(Base): __tablename__ = 'user' id = Column(Integer, primary_key=True) flickr_id = Column(Text) name = Column(Text) def __repr__(self): return quot;<User('%s','%s','%s')>quot; % ( self.id, self.flickr_id, self.name)
  • 57. class Group(Base): __tablename__ = 'flickr_group' id = Column(Integer, primary_key=True) flickr_id = Column(Text) name = Column(Text) throttle_count = Column(Integer) throttle_mode = Column(Text) throttle_remaining = Column(Integer) def __repr__(self): return quot;<Group('%s','%s','%s','%s')>quot; % ( self.id, self.flickr_id, self.name, self.throttle_remaining )
  • 58. class Photo(Base): __tablename__ = 'photo' id = Column(Integer, primary_key=True) flickr_id = Column(Text) title = Column(Text) user_id = Column(Integer,ForeignKey('user.id')) user = relation(User, backref=backref('photos', order_by=id)) groups = relation('Group', secondary=flickr_group_photo, backref=backref('photos')) url = Column(Text) pub_date = Column(DateTime) def __repr__(self): return quot;<Photo('%s','%s','%s','%s')>quot; % ( self.id, self.flickr_id, self.title, self.url )
  • 59. Session = sessionmaker(bind = engine) session = Session() for u in session.query(User): print u for g in session.query(Group): print g for p in session.query(Photo): print p
  • 60. And more  Advanced mapping  Multiple table mapping
  • 61. Elixir  a simpler way of doing declarative ORM for SQLAlchemy
  • 62. from elixir import * class User(Entity): using_options(tablename = 'user') flickr_id = Field(Text) name = Field(Text) photos = OneToMany('Photo') def __repr__(self): return quot;<User('%s','%s','%s')>quot; % ( self.id, self.flickr_id, self.name)
  • 63. class Group(Entity): using_options(tablename = 'flickr_group') flickr_id = Field(Text) name = Field(Text) throttle_count = Field(Integer) throttle_mode = Field(Text) throttle_remaining = Field(Integer) def __repr__(self): return quot;<Group('%s','%s','%s','%s')>quot; % ( self.id, self.flickr_id, self.name, self.throttle_remaining )
  • 64. class Photo(Entity): using_options(tablename = 'photo') flickr_id = Field(Text) title = Field(Text) url = Column(Text) pub_date = Column(DateTime) groups = ManyToMany('Group') user = ManyToOne('User') def __repr__(self): return quot;<Photo('%s','%s','%s','%s')>quot; % ( self.id, self.flickr_id, self.title, self.url )
  • 65. engine = create_engine( 'mysql://twl:pass@localhost/sqlobject', echo=True) Session = sessionmaker(bind = engine) session = Session() metadata = MetaData() metadata.bind='mysql://twl:pass@localhost/sqlobject' metadata.bind.echo = True setup_all() for u in session.query(User): print u for g in session.query(Group): print g for p in session.query(Photo): print print
  • 66. SqlSoup from sqlalchemy.ext.sqlsoup import SqlSoup soup = SqlSoup('mysql://twl:pass@localhost/ sqlobject') soup.photo.all()
  • 67. soup.photo.order_by(soup.photo.title).all() [MappedPhoto(id=71L,flickr_id='3286255071',title='', user_id=1L,url='http://farm4.static.flickr.com/ 3249/3286255071_ff168f220b.jpg',pub_date=datetime.da tetime(2009, 2, 16, 20, 47, 56)), MappedPhoto(id=72L,flickr_id='3287070244',title='',u ser_id=1L,url='http://farm4.static.flickr.com/ 3298/3287070244_87a2a1b3ed.jpg',pub_date=datetime.da tetime(2009, 2, 16, 20, 47, 22)), MappedPhoto(id=46L,flickr_id='3395647634',title='And y Dustman',user_id=1L,url='http:// farm4.static.flickr.com/ 3554/3395647634_cc0c9f5a0a.jpg',pub_date=datetime.da tetime(2009, 3, 29, 9, 7, 34)), MappedPhoto(id=73L,flickr_id='3277628077',title='Bai nbridge Island Chinese New Year 2009',user_id=1L,url='http:// farm4.static.flickr.com/ 3334/3277628077_78025002f5.jpg',pub_date=datetime.da tetime(2009, 2, 13, 23, 31, 52)),
  • 68. Migrations  sqlalchemy-migrate  Version control a database  A repository of upgrade scripts
  • 69. from sqlalchemy import * from migrate import * metadata = MetaData(migrate_engine) photos_table = Table('photo', metadata, Column('id', Integer, primary_key=True), Column('flickr_id', Text), Column('title', Text), Column('user_id', Integer), Column('url', Text), Column('pub_date', DateTime), ) visible_col = Column('visible', Integer) def upgrade(): visible_col.create(photos_table) assert visible_col is photos_table.c.visible def downgrade(): visible_col.drop()
  • 70. from sqlalchemy import * from migrate import * metadata = MetaData(migrate_engine) photos_table = Table('photo', metadata, Column('id', Integer, primary_key=True), Column('flickr_id', Text), Column('title', Text), Column('user_id', Integer), Column('url', Text), Column('pub_date', DateTime), Column('visible', Integer) ) col = photos_table.c.visible def upgrade(): col.alter(type=Boolean, nullable=False) def downgrade(): col.alter(type=Integer, nullable=True)
  • 71. Migration operations  Create/Drop a table  Create/Drop/Alter a column  Create/Drop index  Create/Drop primary/foreign key constraints
  • 72. Summary  Django for Django  SQLAlchemy for the rest