sqlalchemy core: an introduction

39
SQLALCHEMY CORE AN INTRODUCTION / Jason Myers @jasonamyers Background by maul555

Upload: jason-myers

Post on 10-Jul-2015

518 views

Category:

Technology


3 download

TRANSCRIPT

Page 1: SQLAlchemy Core: An Introduction

SQLALCHEMY COREAN INTRODUCTION

/ Jason Myers @jasonamyers

Background by maul555

Page 2: SQLAlchemy Core: An Introduction
Page 3: SQLAlchemy Core: An Introduction

DIFFERENCES BETWEEN CORE AND ORM

Page 4: SQLAlchemy Core: An Introduction

ORM - DOMAIN MODELclass User(Base): __tablename__ = 'users'

id = Column(Integer, primary_key=True) name = Column(String) fullname = Column(String) password = Column(String)

Page 5: SQLAlchemy Core: An Introduction

CORE - SCHEMA-CENTRIC MODELfrom sqlalchemy import Table, Column, Integer, String, MetaDatametadata = MetaData()users = Table('users', metadata, Column('id', Integer, primary_key=True), Column('name', String), Column('fullname', String),)

Page 6: SQLAlchemy Core: An Introduction

STRUCTURE

Copyright © 2014 Mochimochi Land

Page 7: SQLAlchemy Core: An Introduction

STRUCTURE

Page 8: SQLAlchemy Core: An Introduction
Page 9: SQLAlchemy Core: An Introduction

INSTALLINGpip install sqlalchemy

pip install flask-sqlalchemy

bin/paster create -t pyramid_alchemy tutorial

Page 10: SQLAlchemy Core: An Introduction

INITIALIZINGimport sqlalchemyfrom sqlalchemy import create_engineengine = create_engine('sqlite:///:memory:')

Page 11: SQLAlchemy Core: An Introduction

DEFINING A TABLEfrom sqlalchemy import Table, Column, Integer, String, MetaData, ForeignKeymetadata = MetaData()actors = Table('actors', metadata, Column('id', Integer, primary_key=True), Column('name', String), Column('fullname', String), Column('body_count', Integer))roles = Table('roles', metadata, Column('id', Integer, primary_key=True), Column('actor_id', None, ForeignKey('actors.id')), Column('character_name', String, nullable=False))

Page 12: SQLAlchemy Core: An Introduction

CREATE THE TABLESmetadata.create_all(engine)

Page 13: SQLAlchemy Core: An Introduction

TABLE OBJECTSactors.columns.items()

[ ('id', Column('id', Integer(), table=actors, primary_key=True...)), ('name', Column('name', String(), table=actors)), ('fullname', Column('fullname', String(), table=actors)), ('body_count', Column('body_count', Integer(), table=actors))]

Page 14: SQLAlchemy Core: An Introduction

OPENING A CONNECTIONconn = engine.connect()

Page 15: SQLAlchemy Core: An Introduction

SINGLE INSERTins = actors.insert().values(name='Graham', fullname='Graham Chapman', body_count=3)result = conn.execute(ins)result.inserted_primary_key

[1]

Page 16: SQLAlchemy Core: An Introduction

LOOKING AT WHAT WAS EXECUTEDprint str(ins)ins.compile().params

INSERT INTO actors (name, fullname, body_count) VALUES (:name, :fullname, :body_count){'body_count': 3, 'fullname': 'Graham Chapman', 'name': 'Graham'}

Page 17: SQLAlchemy Core: An Introduction

MULTIPLE INSERTresults = conn.execute(roles.insert(), [ {'actor_id': 1, 'character_name' : 'King Arthur'}, {'actor_id': 1, 'character_name' : 'Voice of God'}, {'actor_id': 2, 'character_name' : 'Sir Lancelot'}, {'actor_id': 2, 'character_name' : 'Black Knight'}, {'actor_id': 3, 'character_name' : 'Patsy'}, {'actor_id': 3, 'character_name' : 'Sir Bors'},])results.rowcount

6

Page 18: SQLAlchemy Core: An Introduction

UPDATEstmt = actors.update().where(actors.c.name == 'Graham').values(name='Gram')result = conn.execute(stmt)result.rowcount

1

Page 19: SQLAlchemy Core: An Introduction

DELETEresult = conn.execute(actors.delete().where(actors.c.name == 'Terry'))result.rowcount

1

Page 20: SQLAlchemy Core: An Introduction

SELECTINGs = select([actors.c.name, actors.c.fullname])result = conn.execute(s)for row in result: print row

(u'Graham', u'Graham Chapman')(u'John', u'John Cleese')(u'Terry', u'Terry Gilliam')

Page 21: SQLAlchemy Core: An Introduction

ORDERINGstmt = select([actors.c.name]).order_by(actors.c.name.desc())conn.execute(stmt).fetchall()

[(u'Terry',), (u'John',), (u'Graham',)]

Page 22: SQLAlchemy Core: An Introduction

LIMITINGstmt = select([actors.c.name, actors.c.fullname]).limit(1).offset(1)conn.execute(stmt).first()

(u'John', u'John Cleese')

Page 23: SQLAlchemy Core: An Introduction

COUNTfrom sqlalchemy.sql import funcstmt = select([func.count(actors)])conn.execute(stmt).scalar()

2

Page 24: SQLAlchemy Core: An Introduction

SUMstmt = select([func.count(actors), func.sum(actors.c.body_count)])conn.execute(stmt).first()

(2, 5)

Page 25: SQLAlchemy Core: An Introduction

JOINSs = select([actors, roles]).where(actors.c.id == roles.c.actor_id)for row in conn.execute(s): print row

(1, u'Graham', u'Graham Chapman', 1, 1, u'King Arthur')(1, u'Graham', u'Graham Chapman', 2, 1, u'Voice of God')(2, u'John', u'John Cleese', 3, 2, u'Sir Lancelot')(2, u'John', u'John Cleese', 4, 2, u'Black Knight')(3, u'Terry', u'Terry Gilliam', 5, 3, u'Patsy')(3, u'Terry', u'Terry Gilliam', 6, 3, u'Sir Bors')

Page 26: SQLAlchemy Core: An Introduction

GROUPINGstmt = select([actors.c.name, func.count(roles.c.id)]).\ select_from(actors.join(roles)).\ group_by(actors.c.name)conn.execute(stmt).fetchall()

[(u'Graham', 2), (u'John', 2), (u'Terry', 2)]

Page 27: SQLAlchemy Core: An Introduction

FILTERINGfrom sqlalchemy.sql import and_, or_, not_stmt = select([actors.c.name, roles.c.character_name]).\ where( and_( actors.c.name.like('Gra%'), roles.c.character_name.like('Vo%'), actors.c.id == roles.c.actor_id ) )conn.execute(stmt).fetchall()

[(u'Graham', u'Voice of God')]

Page 28: SQLAlchemy Core: An Introduction

AND SO ON...

Page 29: SQLAlchemy Core: An Introduction
Page 30: SQLAlchemy Core: An Introduction

COMMON DIALECTSInformixMS SQLOraclePostgresSQLiteCustom

Page 31: SQLAlchemy Core: An Introduction

BUT WHAT IF...class UnloadFromSelect(Executable, ClauseElement):

def __init__(self, select, bucket, access_key, secret_key): self.select = select self.bucket = bucket self.access_key = access_key self.secret_key = secret_key

@compiles(UnloadFromSelect)def visit_unload_from_select(element, compiler, **kw): return "unload ('%(query)s') to '%(bucket)s' credentials 'aws_access_key_id=%(access_key)s; aws_secret_access_key=%(secret_key)s' delimiter ',' addquotes allowoverwrite" % { 'query': compiler.process(element.select, unload_select=True, literal_binds=True), 'bucket': element.bucket, 'access_key': element.access_key, 'secret_key': element.secret_key, }

Page 32: SQLAlchemy Core: An Introduction

EXAMPLE STATEMENTunload = UnloadFromSelect( select([fields]), '/'.join(['s3:/', BUCKET, filename]), ACCESS_KEY, SECRET_KEY)

Page 33: SQLAlchemy Core: An Introduction

EXAMPLE USAGEunload ( 'select * from venue where venueid in ( select venueid from venue order by venueid desc limit 10)')to 's3://mybucket/venue_pipe_'credentials 'aws_access_key_id=ACCESS_KEY; aws_secret_access_key=SECRET_KEY';

Page 34: SQLAlchemy Core: An Introduction

DYNAMIC TABLE INTROSPECTIONdef build_table(engine, table_name): return Table(table_name, metadata, autoload=True, autoload_with=engine)

Page 35: SQLAlchemy Core: An Introduction

CHECKING FOR NULL COLUMNSbuild_table(engine, 'census')unavailable_fields = [ c.name for c in t.c if isinstance(c.type, NullType)]

Page 36: SQLAlchemy Core: An Introduction

CHAININGs = select( [ t.c.race, t.c.factor, func.sum(g.t.c.value).label('summed') ], t.c.race > 0 ).where( and_( t.c.type == 'POVERTY', t.c.value != 0 ) ).group_by( t.c.race, t.c.factor ).order_by( t.c.race, t.c.factor)

Page 37: SQLAlchemy Core: An Introduction

CONDITIONALSs = select( [ table.c.discharge_year, func.count(1).label( 'patient_discharges'), table.c.zip_code, ], table.c.discharge_year.in_(years)).group_by(table.c.discharge_year)s = s.where(table.c.hospital_name == provider)

if 'total_charges' not in unavailable_fields: s = s.column( func.sum(table.c.total_charges ).label('patient_charges') )

Page 38: SQLAlchemy Core: An Introduction

s = s.group_by(table.c.zip_code)s = s.order_by('discharges DESC')

cases = conn.execute(s).fetchall()

Page 39: SQLAlchemy Core: An Introduction

QUESTIONS

THANK YOU / Jason Myers @jasonamyers