KEMBAR78
SQLAlchemy Core: An Introduction | PDF
SQLALCHEMY CORE
AN INTRODUCTION
/JasonMyers @jasonamyers
Backgroundbymaul555
DIFFERENCES BETWEEN CORE AND ORM
ORM - DOMAIN MODEL
classUser(Base):
__tablename__='users'
id=Column(Integer,primary_key=True)
name=Column(String)
fullname=Column(String)
password=Column(String)
CORE - SCHEMA-CENTRIC MODEL
fromsqlalchemyimportTable,Column,Integer,String,MetaData
metadata=MetaData()
users=Table('users',metadata,
Column('id',Integer,primary_key=True),
Column('name',String),
Column('fullname',String),
)
STRUCTURE
Copyright©2014MochimochiLand
STRUCTURE
INSTALLING
pip installsqlalchemy
pip installflask-sqlalchemy
bin/paster create -tpyramid_alchemytutorial
INITIALIZING
importsqlalchemy
fromsqlalchemyimportcreate_engine
engine=create_engine('sqlite:///:memory:')
DEFINING A TABLE
fromsqlalchemyimportTable,Column,Integer,String,MetaData,ForeignKey
metadata=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)
)
CREATE THE TABLES
metadata.create_all(engine)
TABLE OBJECTS
actors.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))
]
OPENING A CONNECTION
conn=engine.connect()
SINGLE INSERT
ins=actors.insert().values(name='Graham',fullname='GrahamChapman',body_count=3)
result=conn.execute(ins)
result.inserted_primary_key
[1]
LOOKING AT WHAT WAS EXECUTED
printstr(ins)
ins.compile().params
INSERTINTOactors(name,fullname,body_count)VALUES(:name,:fullname,:body_count)
{'body_count':3,'fullname':'GrahamChapman','name':'Graham'}
MULTIPLE INSERT
results=conn.execute(roles.insert(),[
{'actor_id':1,'character_name':'KingArthur'},
{'actor_id':1,'character_name':'VoiceofGod'},
{'actor_id':2,'character_name':'SirLancelot'},
{'actor_id':2,'character_name':'BlackKnight'},
{'actor_id':3,'character_name':'Patsy'},
{'actor_id':3,'character_name':'SirBors'},
])
results.rowcount
6
UPDATE
stmt=actors.update().where(actors.c.name=='Graham').values(name='Gram')
result=conn.execute(stmt)
result.rowcount
1
DELETE
result=conn.execute(actors.delete().where(actors.c.name=='Terry'))
result.rowcount
1
SELECTING
s=select([actors.c.name,actors.c.fullname])
result=conn.execute(s)
forrowinresult:
printrow
(u'Graham',u'GrahamChapman')
(u'John',u'JohnCleese')
(u'Terry',u'TerryGilliam')
ORDERING
stmt=select([actors.c.name]).order_by(actors.c.name.desc())
conn.execute(stmt).fetchall()
[(u'Terry',),(u'John',),(u'Graham',)]
LIMITING
stmt=select([actors.c.name,actors.c.fullname]).limit(1).offset(1)
conn.execute(stmt).first()
(u'John',u'JohnCleese')
COUNT
fromsqlalchemy.sqlimportfunc
stmt=select([func.count(actors)])
conn.execute(stmt).scalar()
2
SUM
stmt=select([func.count(actors),func.sum(actors.c.body_count)])
conn.execute(stmt).first()
(2,5)
JOINS
s=select([actors,roles]).where(actors.c.id==roles.c.actor_id)
forrowinconn.execute(s):
printrow
(1,u'Graham',u'GrahamChapman',1,1,u'KingArthur')
(1,u'Graham',u'GrahamChapman',2,1,u'VoiceofGod')
(2,u'John',u'JohnCleese',3,2,u'SirLancelot')
(2,u'John',u'JohnCleese',4,2,u'BlackKnight')
(3,u'Terry',u'TerryGilliam',5,3,u'Patsy')
(3,u'Terry',u'TerryGilliam',6,3,u'SirBors')
GROUPING
stmt=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)]
FILTERING
fromsqlalchemy.sqlimportand_,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'VoiceofGod')]
AND SO ON...
COMMON DIALECTS
Informix
MS SQL
Oracle
Postgres
SQLite
Custom
BUT WHAT IF...
classUnloadFromSelect(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)
defvisit_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','
addquotesallowoverwrite"%{
'query':compiler.process(element.select,
unload_select=True,literal_binds=True),
'bucket':element.bucket,
'access_key':element.access_key,
'secret_key':element.secret_key,
}
EXAMPLE STATEMENT
unload=UnloadFromSelect(
select([fields]),
'/'.join(['s3:/',BUCKET,filename]),
ACCESS_KEY,
SECRET_KEY
)
EXAMPLE USAGE
unload(
'select*fromvenuewherevenueidin(
selectvenueidfromvenueorderbyvenueiddesclimit10)'
)
to's3://mybucket/venue_pipe_'
credentials'aws_access_key_id=ACCESS_KEY;
aws_secret_access_key=SECRET_KEY';
DYNAMIC TABLE INTROSPECTION
defbuild_table(engine,table_name):
returnTable(table_name,metadata,autoload=True,autoload_with=engine)
CHECKING FOR NULL COLUMNS
build_table(engine,'census')
unavailable_fields=[
c.nameforcint.cifisinstance(c.type,NullType)
]
CHAINING
s=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)
CONDITIONALS
s=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'notinunavailable_fields:
s=s.column(
func.sum(table.c.total_charges
).label('patient_charges')
)
s=s.group_by(table.c.zip_code)
s=s.order_by('dischargesDESC')
cases=conn.execute(s).fetchall()
QUESTIONS
THANK YOU
/JasonMyers @jasonamyers

SQLAlchemy Core: An Introduction