Download - SQLAlchemy Primer
![Page 1: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/1.jpg)
SQLAlchemy Primer(extra content)
for Kobe Python Meetup #13 2017/09/15 Kobe Japan
![Page 2: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/2.jpg)
Yasushi Masuda PhD ( @whosaysni )
Tech team, Core IT grp. IT Dept. MonotaRO Co., LTD.
Pythonista since 2001 (2.0~) • elaphe (barcode library) • oikami.py (老神.py) • PyCon JP founder
Japanese Translation works
![Page 3: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/3.jpg)
Agenda
Myths
Core concepts in SQLAlchemy
Engine basics (+hands-on)
ORM primer (+hans-on)
![Page 4: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/4.jpg)
References
Online Document:http://docs.sqlalchemy.org/
en/rel_1_1/
(Old) Japanese translation:http://omake.accense.com/static/doc-ja/sqlalchemy/
![Page 5: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/5.jpg)
Preparationsakila DB on SQLite http://bit.ly/2fdeeft
https://github.com/jOOQ/jOOQ/jOOQ-examples/Sakila/sqlite-sakila-db/sqlite-sakila.sq
Sakila • Demonstration
DB for MySQL • Models a rental
video shop • BSD License
Schema described at: https://dev.mysql.com/doc/sakila/en/sakila-structure-tables.html
![Page 6: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/6.jpg)
Myths[WRONG!] It's just an ORM libraryNot limited to. SQLAlchemy is a DB manipulation framework.
[WRONG!] SA is built on ORMNO. Connection management and SQL expression framework are its core.ORM is built on them.[WRONG!] SA cannot handle raw SQLTable definition is not required. Even textual SQL is available.
[WRONG!] SA automatically escapes value for youSQLAlchemy relies value escaping on DB-API, while it escapes schema, table, column names. SQLAlchemy generates parameterized query that helps DB-API level escaping.
[WRONG!] Only Python adept can handle SASQLAlchemy is EASY. You may need SQL and RDBMS experience. Let's see!
[AGREE] Documentation is somewhat difficult to understandAgreed.
![Page 7: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/7.jpg)
Core concepts
![Page 8: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/8.jpg)
http://docs.sqlalchemy.org/en/latest/index.html
![Page 9: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/9.jpg)
http://docs.sqlalchemy.org/en/latest/index.html
SQLAlchemy Core
Engine (connection) Schema definitionSQL Expression
SQLAlchemy ORM
Mapper Declarative Mapper
Session
Dialect DB Backend-specific functionalities
![Page 10: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/10.jpg)
Engine manages DB connection(s)
SQL Expressiondescribes SQL statement in Python
Mappingreflects DB record with Python object
Dialect DB Backend specific functionalities
![Page 11: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/11.jpg)
DatabaseYour program
SQL construction
Query execution
Typeconversion
Parameter binding
Driver Setup
Connection management
Result data structure
Value escaping
Schema name
Type conversion
Dialect-specific
Query Construction
Query Execution
Result
Schema object Object-relational mapping
High-level Interface
DB Session
![Page 12: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/12.jpg)
Engine
![Page 13: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/13.jpg)
DB API DB ServerProgram
Issues around DB-API
Which DB-API to use How to initialize the DB-API
How to generate valid query for it How to handle cursor on the DB-API How to execute query on the DB-API How to retrieve result from DB-API How to reserve/reuse connection
![Page 14: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/14.jpg)
DB API DB ServerProgram
Engine resolves issues
Select DB-API from DSN URL Initialize DB-API for you
Accept string and SQL expression Manage cursor for you
Unify execution/transaction API Handle result via ResultProxy Pool connection automatically
Engine
![Page 15: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/15.jpg)
Engine DB API DB ServerProgram
>>>fromsqlalchemyimportcreate_engine>>>
![Page 16: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/16.jpg)
Engine DB API DB ServerProgram
>>>fromsqlalchemyimportcreate_engine>>>e=create_engine('sqlite://')#SQLitememoryengine>>>
![Page 17: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/17.jpg)
Engine DB API DB ServerProgram
#UseURLforspecifyingdatabase>>>e=create_engine('sqlite://')#SQLitememoryengine>>>e=create_engine('sqlite:///path_to_db.sqlite3')#sqlite3>>>e=create_engine('mysql://scott:tiger@dbserv/dbname')#mysql>>>e=create_engine('mssql://bill:gates@dbserv/dbname')#mssql>>>
![Page 18: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/18.jpg)
Engine DB API DB ServerProgram
#Becarefulwithnumberofslashes>>>e=create_engine('sqlite:///sqlite-sakila.sq')>>>e=create_engine('sqlite:////<absolute_path>/sqlite-sakila.sq')
![Page 19: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/19.jpg)
Engine DB API DB ServerProgram
>>>e=create_engine('sqlite:///sqlite-sakila.sq')>>>eEngine(sqlite:///sakila-data.sq)
#executereturnsResultProxy>>>q='selecttitlefromfilmlimit5')>>>res=e.execute(q)>>>res<sqlalchemy.engine.result.ResultProxyobjectat0x10da96990>>>>
![Page 20: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/20.jpg)
Engine DB API DB ServerProgram
>>>e=create_engine('sqlite:///sqlite-sakila.sq')>>>eEngine(sqlite:///sakila-data.sq)
#executereturnsResultProxy>>>q='selecttitlefromfilmlimit5')>>>res=e.execute(q)>>>res<sqlalchemy.engine.result.ResultProxyobjectat0x10da96990>>>forrowinres:#ResultProxycanbeiterated/namedtupleaccess...print(row.title)...ACADEMYDINOSAURACEGOLDFINGERADAPTATIONHOLESAFFAIRPREJUDICEAFRICANEGG>>>
![Page 21: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/21.jpg)
Engine DB API DB ServerProgram
>>>q='selectfilm_id,titlefromfilmlimit10'>>>rows=list(e.execute(q))>>>rows[2][1]#eachrowisaccessiblelikeastuple'ADAPTATIONHOLES'>>>rows[4]['title']#rowcanbeaccessiblelikeasdictionary'AFRICANEGG'
>>>res=e.execute(q)>>>forfid,titleinres:#canbeexpandedasnormaltuple...print((fid,title))...(1,'ACADEMYDINOSAUR')(2,'ACEGOLDFINGER')(3,'ADAPTATIONHOLES')(4,'AFFAIRPREJUDICE')(5,'AFRICANEGG')>>>rows=list(e.execute(q))>>>
![Page 22: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/22.jpg)
transaction
>>>t=e.begin()>>>t.transaction<sqlalchemy...RootTransactionobjectat...>>>>t.transaction.commit()
#withstatementhandlestransactionsmart>>>withe.begin():e.execute(...)>>>#(transactioncommittedautomatically)
![Page 23: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/23.jpg)
HANDS ON: Engine basics
Connecttosqlite-sakila.sqdatabase
Listactorsinfilm"DINOSAURSECRETARY"
![Page 24: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/24.jpg)
HANDS ON: Engine basics
>>>e=create_engine('sqlite:///sqlite-sakila.sq')>>>q='''selecta.first_name,a.last_name...fromfilmasf...innerjoinfilm_actorasfa...onf.film_id=fa.film_id...innerjoinactorasa...onfa.actor_id=a.actor_id...wheref.title="DINOSAURSECRETARY"'''>>>forfirst_name,last_nameine.execute(q):...print('{}{}'.format(first_name,last_name))...LUCILLETRACYBURTDUKAKISJAYNENEESONRUSSELLBACALLPENELOPEMONROEMINNIEKILMER
![Page 25: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/25.jpg)
SQL expression
![Page 26: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/26.jpg)
Remember: SQL is a language
SELECT[ALL|DISTINCT[ON(expression[,...])]]
[*|expression[[AS]output_name][,...]]
[FROMfrom_item[,...]]
[WHEREcondition]
[GROUPBYgrouping_element[,...]]
[ORDERBYexpression[ASC|DESC|USINGoperator][NULLS{FIRST|LAST}][,...]]
[LIMIT{count|ALL}]
![Page 27: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/27.jpg)
Remember: SQL is a language
SELECT[ALL|DISTINCT[ON(expression[,...])]]
[*|expression[[AS]output_name][,...]]
[FROMfrom_item[,...]]
[WHEREcondition]
[GROUPBYgrouping_element[,...]]
[ORDERBYexpression[ASC|DESC|USINGoperator][NULLS{FIRST|LAST}][,...]]
[LIMIT{count|ALL}]
STATEMENT
![Page 28: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/28.jpg)
Remember: SQL is a language
SELECT[ALL|DISTINCT[ON(expression[,...])]]
[*|expression[[AS]output_name][,...]]
[FROMfrom_item[,...]]
[WHEREcondition]
[GROUPBYgrouping_element[,...]]
[ORDERBYexpression[ASC|DESC|USINGoperator][NULLS{FIRST|LAST}][,...]]
[LIMIT{count|ALL}]
CLAUSE
CLAUSE
CLAUSE
CLAUSE
CLAUSE
CLAUSE
![Page 29: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/29.jpg)
Remember: SQL is a language
SELECT[ALL|DISTINCT[ON(expression[,...])]]
[*|expression[[AS]output_name][,...]]
[FROMfrom_item[,...]]
[WHEREcondition]
[GROUPBYgrouping_element[,...]]
[ORDERBYexpression[ASC|DESC|USINGoperator][NULLS{FIRST|LAST}][,...]]
[LIMIT{count|ALL}]
parameter
parameter
expression
expression
expression
expression
expression
expression
![Page 30: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/30.jpg)
Remember: SQL is a Language
SELECT
FROM selectablesselectable
join
WHERE
selectable
selectable
GROUP BY ORDER BY
expression
expressioncondition
expression
expressionsexpression
expression
SELECT statement
![Page 31: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/31.jpg)
SELECTA.name,B.title,C.title
FROMartistsasAINNERJOINalbumasBONA.id=B.artist_idINNERJOINmusicasCONB.id=C.album
WHEREA.nameLIKE'%Astor%'ANDA.yearBETWEEN1970AND2010ANDC.titleLIKE'%Tango%'
From SQL to Python
![Page 32: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/32.jpg)
SELECT<column>,<column>,...
FROM<selectable>INNERJOIN<selectable>ON<condition>INNERJOIN<selectable>ON<condition>...
WHERE<condition>AND<condition>AND<condition>
GROUPBY...LIMIT...
Clauses
![Page 33: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/33.jpg)
SELECT<[<column>,<column>,<column>]>
FROM<join(<selectable>,<selectable>,...)>
WHERE<and(<condition>,<condition>,...)>
Statement and subjects
![Page 34: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/34.jpg)
SELECT<expressions>
FROM<selectable>
WHERE<conditions>
... simplifed
![Page 35: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/35.jpg)
<selectstatement>
..., finally
![Page 36: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/36.jpg)
engine.execute(<selectstatement>)
If query is "an object"...
Query object
![Page 37: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/37.jpg)
>>>query=select(...)
>>>engine.execute(query)
... it can be "execute()-able"
Engine "compiles" query into string and execute it
(according to dialect)
![Page 38: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/38.jpg)
query=select(
<expression>,
from_obj=<selectables>,
whereclause=<conditions>,
)
clauses as parameters
![Page 39: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/39.jpg)
columns=[col1,col2,...]
fromobj=join(tbl1,tbl2,...)
where=and_(expr1,expr2,...)
query_expr=select(columns,from_obj=fromobj,whereclause=where)
query with SQL expression
![Page 40: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/40.jpg)
>>>fromsqlalchemy.sqlimportselect,text>>>q=select([text('*')])
building sql statement with basic sql expression
![Page 41: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/41.jpg)
>>>fromsqlalchemy.sqlimportselect,text>>>q=select([text('*')])>>>q<sqlalchemy.....Selectat...;Selectobject>>>>str(q)'SELECT*'>>>q=select([text('*')],...from_obj=text('foo'),...whereclause=text('id=3'))>>>str(q)'SELECT*\nFROMfoo\nWHEREid=3'
building sql statement with basic sql expression
![Page 42: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/42.jpg)
>>>fromsqlalchemy.sqlimportselect,text>>>q=select([text('*')])>>>q<sqlalchemy.....Selectat...;Selectobject>>>>str(q)'SELECT*'>>>q=select([text('*')],...from_obj=text('foo'),...whereclause=text('id=3'))>>>str(q)'SELECT*\nFROMfoo\nWHEREid=3'
building sql statement with basic sql expression
![Page 43: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/43.jpg)
elements: table and columnSchema
Table Table Table
...
Column
Column
Column
...
Column
Column
Column
...
Column
Column
Column
...
SchemaTable Table Table
Column
Column
Column
Column
Column
Column
...
![Page 44: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/44.jpg)
elements: table and column>>>fromsqlalchemy.sqlimportcolumn,table>>>fromsqlalchemyimportINTEGER
![Page 45: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/45.jpg)
elements: table and column>>>fromsqlalchemy.sqlimportcolumn,table>>>fromsqlalchemyimportINTEGER>>>c=column('name')#simplest>>>c=column('name',type_=INTEGER)
![Page 46: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/46.jpg)
elements: table and column>>>fromsqlalchemy.sqlimportcolumn,table>>>fromsqlalchemyimportINTEGER>>>c=column('name')#simplest>>>c=column('name',type_=INTEGER)>>>c<sqlalchemy....ColumnClauseat...;name>>>>str(c)'name'
![Page 47: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/47.jpg)
elements: table and column>>>fromsqlalchemy.sqlimportcolumn,table>>>fromsqlalchemyimportINTEGER>>>c=column('name')#simplest>>>c=column('name',type_=INTEGER)>>>c<sqlalchemy....ColumnClauseat...;name>>>>str(c)'name'>>>c.table#None>>>t1=table('artist')>>>c.table=t1>>>str(c)'artist.name'
![Page 48: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/48.jpg)
>>>t=table('tbl1',column('col1'),...)
defining table with columnsTable name List of columns
![Page 49: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/49.jpg)
>>>t=table('tbl1',column('col1'),...)
>>>t.c.col1
<sqlalchemy.....ColumnClauseat...;col1>
defining table with columnsTable name List of columns
![Page 50: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/50.jpg)
>>>t=table('tbl1',column('col1'),...)
>>>t.c.col1
<sqlalchemy.....ColumnClauseat...;col1>
>>>t.schema='db1'
>>>str(t.c.col1)
'db1.tbl1.col1'
defining table with columnsTable name List of columns
![Page 51: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/51.jpg)
>>>t=table('tbl1',column('col1'),column('col2'))
select() with table element
![Page 52: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/52.jpg)
>>>t=table('tbl1',column('col1'),column('col2'))>>>print(select([t]))SELECTtbl1.col1,tbl1.col2FROMtbl1
select() with table element
![Page 53: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/53.jpg)
>>>t=table('tbl1',column('col1'),column('col2'))>>>print(select([t]))SELECTtbl1.col1,tbl1.col2FROMtbl1
#columnlabeling>>>print(select([t.c.col1.label('col_alias1')])SELECTtbl1.col1as"col_alias1"FROMtbl1
select() with table element
![Page 54: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/54.jpg)
>>>t=table('tbl1',column('col1'),column('col2'))>>>print(select([t]))SELECTtbl1.col1,tbl1.col2FROMtbl1
#columnlabeling>>>print(select([t.c.col1.label('col_alias1')])SELECTtbl1.col1as"col_alias1"FROMtbl1
#tablealias>>>t_A,t_B=alias(t,'A'),alias(t,'B')>>>print(select([t_A.c.col1,t_B.c.col2]))SELECT"A".col1,"B".col2FROMtbl1AS"A",tbl1AS"B"
select() with table element
![Page 55: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/55.jpg)
howtoworkwith
wheretbl1.col1=42
conditionals
![Page 56: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/56.jpg)
howtoworkwith
wheretbl1.col1=42
conditionals
conditional expression (compare operation)
![Page 57: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/57.jpg)
>>>cond=text('last_nameLIKE%KOV')>>>str(cond)'last_nameLIKE%KOV'
conditional by text()
![Page 58: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/58.jpg)
>>>cond=column('last_name').like('%KOV')>>>cond<sqlalchemy....BinaryExpressionobjectat...>
conditional by like() method
![Page 59: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/59.jpg)
>>>cond=column('last_name').like('%KOV')>>>cond<sqlalchemy....BinaryExpressionobjectat...>>>>str(cond)'last_nameLIKE:last_name_1'
conditional by like() method
placeholder for right value of LIKE
![Page 60: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/60.jpg)
>>>cond=column('last_name').like('%KOV')>>>cond<sqlalchemy....BinaryExpressionobjectat...>>>>str(cond)'last_nameLIKE:last_name_1
>>>cond.rightBindParameter('%(4339977744last_name)s','%KOV',type_=String())
conditional by like() method
![Page 61: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/61.jpg)
>>>column('first_name')='DAVID'File"<stdin>",line1SyntaxError:can'tassigntofunctioncall
conditional by operation
![Page 62: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/62.jpg)
>>>column('first_name')='DAVID'File"<stdin>",line1SyntaxError:can'tassigntofunctioncall
>>>column('first_name')=='DAVID'<sqlalchemy...BinaryExpressionobjectat...>
conditional by operation
![Page 63: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/63.jpg)
>>>column('first_name')='DAVID'File"<stdin>",line1SyntaxError:can'tassigntofunctioncall
>>>column('first_name')=='DAVID'<sqlalchemy...BinaryExpressionobjectat...>
>>>cond=column('first_name')=='DAVID'>>>str(cond)>>>'first_name=:first_name_1'>>>cond.right>>>BindParameter('%(...)s','DAVID',type_=...)
conditional by operation
![Page 64: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/64.jpg)
>>>column('first_name')='DAVID'File"<stdin>",line1SyntaxError:can'tassigntofunctioncall
>>>column('first_name')=='DAVID'<sqlalchemy...BinaryExpressionobjectat...>
>>>cond=column('first_name')=='DAVID'>>>str(cond)>>>'first_name=:first_name_1'>>>cond.right>>>BindParameter('%(...)s','DAVID',type_=...)
>>>str(column('last_name')==None)>>>'last_nameisNULL'
conditional by operation
![Page 65: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/65.jpg)
>>>fromsqlalchemy.sqlimportselect,table,column>>>actor_tbl=table('actor',column('actor_id'),...column('first_name'),column('last_name'))
conditionals in select
![Page 66: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/66.jpg)
>>>fromsqlalchemy.sqlimportselect,table,column>>>actor_tbl=table('actor',column('actor_id'),...column('first_name'),column('last_name'))>>>query=select([actor_tbl],...whereclause=(actor_tbl.c.last_name=='TRACY'))
conditionals in select
![Page 67: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/67.jpg)
>>>fromsqlalchemy.sqlimportselect,table,column>>>actor_tbl=table('actor',column('actor_id'),...column('first_name'),column('last_name'))>>>query=select([actor_tbl],...whereclause=(actor_tbl.c.last_name=='TRACY'))>>>query<sqlalchemy.....Selectat...;Selectobject>>>>print(query)SELECTactor.first_name,actor.last_nameFROMactorWHEREactor.last_name=:last_name_1>>>query.compile().params{'last_name_1':'TRACY'}
conditionals in select
![Page 68: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/68.jpg)
>>>fromsqlalchemy.sqlimportselect,table,column>>>actor_tbl=table('actor',column('actor_id'),...column('first_name'),column('last_name'))>>>query=select([actor_tbl],...whereclause=(actor_tbl.c.last_name=='TRACY'))>>>query<sqlalchemy.....Selectat...;Selectobject>>>>print(query)SELECTactor.actor_id,actor.first_name,actor.last_nameFROMactorWHEREactor.last_name=:last_name_1>>>query.compile().params{'last_name_1':'TRACY'}>>>list(e.execute(query))[(20,'LUCILLE','TRACY'),(117,'RENEE','TRACY')]
conditionals in select
![Page 69: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/69.jpg)
select(...)
SELECT...
select(...).select_from(...)
SELECT...FROM...
select(...).where(...)
SELECT...WHERE...
select(...).where(...).where(...)
SELECT...WHERE...AND...
select(...).where(...).order_by(...)
SELECT...WHERE...ORDERBY...
generative method
![Page 70: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/70.jpg)
actor_tbl.select()SELECT...FROMactor
actor_tbl.select(actor_tbl.c.first_name='BEN')SELECT...FROMactorWHEREfirst_name=...
generative method
![Page 71: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/71.jpg)
HANDS ON: SQL expression
• define actor table with table()/column()
• build query with sql expression to searchactor having initial A.H. (result should include actor_id)
![Page 72: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/72.jpg)
Schema definition
![Page 73: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/73.jpg)
howtoCREATEtable
schema definition
![Page 74: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/74.jpg)
howtoCREATEtable
howtodefinecolumndetailhowtodefineconstraints
schema definition
![Page 75: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/75.jpg)
>>>fromsqlalchemyimportColumn,MetaData,Table>>>user_table=Table(...'user',MetaData(),...Column('id',INTEGER,primary_key=True),...Column('first_name',VARCHAR(45)),...Column('last_name',VARCHAR(45)))>>>
defining table
![Page 76: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/76.jpg)
>>>fromsqlalchemyimportColumn,MetaData,Table>>>user_table=Table(...'user',MetaData(),...Column('id',INTEGER,primary_key=True),...Column('first_name',VARCHAR(45)),...Column('last_name',VARCHAR(45)))>>>user_tableTable('user',MetaData(bind=None),Column...)
defining table
![Page 77: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/77.jpg)
>>>fromsqlalchemyimportColumn,MetaData,Table>>>user_table=Table(...'user',MetaData(),...Column('id',INTEGER,primary_key=True),...Column('first_name',VARCHAR(45)),...Column('last_name',VARCHAR(45)))>>>user_tableTable('user',MetaData(bind=None),Column...)
#CREATETABLEbycrete()>>>user_table.create(bind=e)
#DROPTABLEwithdrop()>>>user_table.drop(bind=e)
defining table
![Page 78: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/78.jpg)
Table/Column vs table/columnVisitable (base type)
ClauseElement
Selectable
FromClause [ table() ]
ColumnElement
ColumnClause [ column() ]
Column Table
SchemaItem
![Page 79: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/79.jpg)
Table/Column vs table/columnVisitable (base type)
ClauseElement
Selectable
FromClause [ table() ]
ColumnElement
ColumnClause [ column() ]
Column Table
SchemaItem
Supprorts same operation
![Page 80: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/80.jpg)
HANDS ON: Schema definition
• define "user" table with Table()/Column()
• create table with .create()
• insert records
• drop table with .drop()
name type options
id INTEGER primary_key
username VARCHAR (64) nullable=False
email VARCHAR(128) nullable=False
![Page 81: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/81.jpg)
ORM basics
![Page 82: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/82.jpg)
Object-Relational Mapping
• Map DB records to objects
• ActiveRecord pattern
• 1 table ~> 1 class, 1 record ~> 1 object
• FK reference -> reference to other object
• column -> property/attribute of object
![Page 83: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/83.jpg)
ORM in SQLAlchemy
• mapper maps a table with Python classmapped class will have instrumented attribute
• Session manipulates DB for you to retrieve / save mapped objects
![Page 84: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/84.jpg)
mappingTable
Column foo
Column bar
Column baz
...
entity class
"mapped" entity class
instrumented fooinstrumented barinstrumented baz
...
method quxmethod quux
method quxmethod quux
...
mapper
![Page 85: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/85.jpg)
classic mapping
[new] declarative mapping
mapping patterns
![Page 86: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/86.jpg)
>>>fromsqlalchemy.ormimportmapper>>>actor_tbl=Table(...)>>>classActor(object):pass>>>mapper(Actor,actor_tbl)>>>dir(Actor)['__class__',...'_sa_class_manager','actor_id','first_name','last_name']>>>Actor.actor_id<...InstrumentedAttributeobjectat...>
classic mapping
![Page 87: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/87.jpg)
>>>fromsqlalchemy.ext.declarativeimportdeclarative_base>>>fromsqlalchmyimportDateTime,Integer,String>>>Base=declarative_base()>>>>>>classActor(Base):...__tablename__='actor'...actor_id=Column(Integer,primary_key=True)...first_name=Column(String)...last_name=Column(String)...last_update=Column(DateTime)
declarative mapping
![Page 88: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/88.jpg)
>>>fromsqlalchemy.ext.declarativeimportdeclarative_base>>>fromsqlalchmyimportDateTime,Integer,String>>>Base=declarative_base()>>>>>>classActor(Base):...__tablename__='actor'...actor_id=Column(Integer,primary_key=True)...first_name=Column(String)...last_name=Column(String)...last_update=Column(DateTime)>>>dir(Actor)['__class__','_decl_class_registry','_sa_class_manager','actor_id','first_name','last_name','last_update','metadata']
declarative mapping
![Page 89: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/89.jpg)
ORM in SQLAlchemy
• mapper maps a table with Python classmapped class will have instrumented attribute
• Session manipulates DB for you to retrieve / save mapped objects
![Page 90: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/90.jpg)
sessionEngineProgram
query Aselect A
record Aobject Bstart
tracking A
...
(updates) flag A as "dirty"
reflect new/dirty changes
flush
starttracking B
...
add object B
update A insert B
commit
begin
![Page 91: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/91.jpg)
Using Session
>>>fromsqlalchemy.ormimportsessionmaker>>>Session=sessionmaker(bind=e)>>>session=Session()>>>>>>
![Page 92: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/92.jpg)
Using Session
>>>fromsqlalchemy.ormimportsessionmaker>>>Session=sessionmaker(bind=e)>>>session=Session()>>>query=session.query(Actor)>>>query<sqlalchemy.orm.query.Queryobjectat...>
![Page 93: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/93.jpg)
Using Session
>>>fromsqlalchemy.ormimportsessionmaker>>>Session=sessionmaker(bind=e)>>>session=Session()>>>query=session.query(Actor)>>>query<sqlalchemy.orm.query.Queryobjectat...>>>>actor=query.first()>>>actor<...ActorObjectat...>
![Page 94: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/94.jpg)
Query object methods: query filtering
>>>q=session.query(Actor)>>>str(q)>>>'SELECT...\nFROMactor'>>>q1=q.filter(Actor.first_name=='BEN')>>>str(q1)'SELECT...\nFROMactor\nWHEREactor.first_name=?'>>>q2=q1.filter_by(last_name='SMITH')>>>str(q2)'SELECT...\nFROMactor\nWHEREactor.first_name=?ANDactor.last_name=?'
![Page 95: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/95.jpg)
Query object methods: fetching record(s)
>>>q=session.query(Actor)>>>q.first()<...Actorobjectat...>
>>>q.all()#WARNING:SELECTsallrecords<...Actorobjectat...>,<...Actorobjectat...>,...
>>>q[:3]<...Actorobjectat...>,<...Actorobjectat...>,...
>>>q.count()200
![Page 96: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/96.jpg)
Update/Insert in Session
>>>session=Session()>>>actor_a=Actor(first_name='KEN',...last_name='WATANABE')>>>session.add(actor_a)>>>session.commit()
>>>actor_b=session.query(Actor).get(1)>>>actor_b.last_name='GEORGE'>>>session.commit()
![Page 97: SQLAlchemy Primer](https://reader034.vdocuments.net/reader034/viewer/2022052302/5a66d2a07f8b9ab87e8b4bbb/html5/thumbnails/97.jpg)
HANDS ON: ORM basics
• define Category model with declarative ORM
• select any record
• add "Nature" category
• delete "Nature" category