
Flask-SQLAlchemy
Eueung Mulyana
http://eueung.github.io/python/flask-sqlalchemy
Python CodeLabs | Attribution-ShareAlike CC BY-SA
1 / 20

Basics #1, #2
Relationships #3, #4, #5
Declarative (ORM) #6
Manual OR Mapping #7
SQL Abstraction Layer #8
2 / 20
Basics
 
3 / 20
Example #1
fromflaskimportFlask
fromflask.ext.sqlalchemyimportSQLAlchemy
#------------------------------------------
app=Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']='sqlite:///test.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=True
db=SQLAlchemy(app)
#------------------------------------------
classUser(db.Model):
id=db.Column(db.Integer,primary_key=True)
username=db.Column(db.String(80),unique=True)
email=db.Column(db.String(120),unique=True)
def__init__(self,username,email):
self.username=username
self.email=email
def__repr__(self):
return'<User%r>'%self.username
db.create_all()
admin=User('admin','admin@example.com')
guest=User('guest','guest@example.com')
db.session.add(admin)
db.session.add(guest)
db.session.commit()
users=User.query.all()
printusers
admin=User.query.filter_by(username='admin').first()
printadmin
[<Useru'admin'>,<Useru'guest'>]
<Useru'admin'>
unicode('abcdef')-> u'abcdef'
u'helloworld'.encode('utf-8')or
str(u'helloworld')
4 / 20
Example #2
3
1
admin@example.com
True
[<Useru'admin'>,<Useru'guest'>]
[<Useru'admin'>,<Useru'guest'>]
[<Useru'admin'>,<Useru'guest'>]
[<Useru'admin'>]
<Useru'admin'>
This will raise 404 errors instead of returning None:
get_or_404()or first_or_404()(for view
functions)
db.create_all()
admin=User('admin','admin@example.com')
guest=User('guest','guest@example.com')
me=User('me','me@example.com')
db.session.add(admin)
db.session.add(guest)
db.session.add(me)
db.session.commit()
printme.id#aftercommit
db.session.delete(me)
db.session.commit()
admin=User.query.filter_by(username='admin').first()
printadmin.id
printadmin.email
missing=User.query.filter_by(username='missing').first()
printmissingisNone
printUser.query.all()
printUser.query.filter(User.email.endswith('@example.com')).a
printUser.query.order_by(User.username).all()
printUser.query.limit(1).all()#1user
printUser.query.get(1)#byprimarykey
5 / 20
Relationships
 
6 / 20
fromflaskimportFlask
fromflask.ext.sqlalchemyimportSQLAlchemy
#------------------------------------------
app=Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']='sqlite:///test.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=True
db=SQLAlchemy(app)
#------------------------------------------
classPerson(db.Model):
id=db.Column(db.Integer,primary_key=True)
name=db.Column(db.String(50))
addresses=db.relationship('Address',backref='person',lazy=
def__init__(self,name):
self.name=name
def__repr__(self):
return'<Person%r>'%self.name
classAddress(db.Model):
id=db.Column(db.Integer,primary_key=True)
email=db.Column(db.String(120),unique=True)
person_id=db.Column(db.Integer,db.ForeignKey('person.id'
#person=db.relationship('Person',backref=db.backref('addresses',lazy='dynamic'))
def__init__(self,email,pers):
self.email=email
self.person_id=pers.id
def__repr__(self):
return'<Address%r>'%self.email
Example #3
How does it know that this will return more than one
address? Because SQLAlchemy guesses a useful default
from your declaration.
If you would want to have a one-to-one relationship you
can pass uselist=Falseto relationship().
Two possibilities (TBT)
See: Declaring Models
7 / 20
Example #3
[<Addressu'otong@example.com'>,<Addressu'otong@nasa.com'
<Addressu'otong@example.com'>
[<Addressu'ujang@example.com'>]
<Personu'otong'>
db.create_all()
otong=Person('otong')
ujang=Person('ujang')
db.session.add(otong)
db.session.add(ujang)
db.session.commit()
otongemail1=Address('otong@example.com',otong)
otongemail2=Address('otong@nasa.com',otong)
ujangemail=Address('ujang@example.com',ujang)
db.session.add(otongemail1)
db.session.add(otongemail2)
db.session.add(ujangemail)
db.session.commit()
printotong.addresses.all()
printotong.addresses.first()
printujang.addresses.all()
printotongemail1.person
8 / 20
Example #4
Page.tags : a list of tags once loaded
Tag.pages : a dynamic backref
Declaring Models — Flask-SQLAlchemy Documentation
Many to Many Relationships with Flask-SQLALchemy
Basic Relationship Patterns — SQLAlchemy
fromflaskimportFlask
fromflask.ext.sqlalchemyimportSQLAlchemy
#------------------------------------------
app=Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']='sqlite:///test.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=True
db=SQLAlchemy(app)
#------------------------------------------
tags=db.Table('tags',
db.Column('tag_id',db.Integer,db.ForeignKey('tag.id')),
db.Column('page_id',db.Integer,db.ForeignKey('page.id'
)
classPage(db.Model):
id=db.Column(db.Integer,primary_key=True)
title=db.Column(db.String(80))
body=db.Column(db.Text)
tags=db.relationship('Tag',secondary=tags,backref=db.b
def__init__(self,title):
self.title=title
def__repr__(self):
return'<Page%r>'%self.title
classTag(db.Model):
id=db.Column(db.Integer,primary_key=True)
label=db.Column(db.String(50))
def__init__(self,label):
self.label=label
def__repr__(self):
return'<Tag%r>'%self.label
9 / 20
db.create_all()
tagpython=Tag('python')
tagtuts=Tag('tutorial')
tagjava=Tag('java')
db.session.add(tagpython)
db.session.add(tagjava)
db.session.add(tagtuts)
#db.session.commit()
pagepython1=Page('pagepython1')
pagepython2=Page('pagepython2')
pagejava=Page('pagejava')
db.session.add(pagepython1)
db.session.add(pagepython2)
db.session.add(pagejava)
#db.session.commit()
pagepython1.tags.append(tagpython)
pagepython1.tags.append(tagtuts)
pagepython2.tags.append(tagpython)
pagejava.tags.append(tagjava)
db.session.commit()
printtagpython.pages.all()
printpagepython1.tags
Example #4
[<Pageu'pagepython1'>,<Pageu'pagepython2'>]
[<Tagu'tutorial'>,<Tagu'python'>]
10 / 20
Example #5
fromdatetimeimportdatetime
fromflaskimportFlask
fromflask.ext.sqlalchemyimportSQLAlchemy
#------------------------------------------
app=Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI']='sqlite:///test.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS']=True
db=SQLAlchemy(app)
#------------------------------------------
classPost(db.Model):
id=db.Column(db.Integer,primary_key=True)
title=db.Column(db.String(80))
body=db.Column(db.Text)
pub_date=db.Column(db.DateTime)
category_id=db.Column(db.Integer,db.ForeignKey('category.id'
category=db.relationship('Category',backref=db.backref(
def__init__(self,title,body,category,pub_date=None)
self.title=title
self.body=body
ifpub_dateisNone:
pub_date=datetime.utcnow()
self.pub_date=pub_date
self.category=category
def__repr__(self):
return'<Post%r>'%self.title
classCategory(db.Model):
id=db.Column(db.Integer,primary_key=True)
name=db.Column(db.String(50))
def__init__(self,name):
self.name=name
def__repr__(self):
return'<Category%r>'%self.name
#------------------------------------------
db.create_all()
py=Category('Python')
p=Post('HelloPython!','Pythonisprettycool',py)
db.session.add(py)
db.session.add(p)
db.session.commit()#journal?
printpy.posts
printpy.posts.all()
SELECTpost.idASpost_id,post.titleASpost_title,post.body
[<Postu'HelloPython!'>]
11 / 20
Declarative
 
12 / 20
Example #6
database.py
fromsqlalchemyimportcreate_engine
fromsqlalchemy.ormimportscoped_session,sessionmaker
fromsqlalchemy.ext.declarativeimportdeclarative_base
#------------------------------------------
engine=create_engine('sqlite:///test.db',convert_unicode=
db_session=scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
Base=declarative_base()
Base.query=db_session.query_property()
#------------------------------------------
definit_db():
importmodels
Base.metadata.create_all(bind=engine)
models.py
fromsqlalchemyimportColumn,Integer,String
fromdatabaseimportBase
#------------------------------------------
classUser(Base):
__tablename__='users'
id=Column(Integer,primary_key=True)
name=Column(String(50),unique=True)
email=Column(String(120),unique=True)
def__init__(self,name=None,email=None):
self.name=name
self.email=email
def__repr__(self):
return'<User%r>'%(self.name)
13 / 20
Example #6
[<Useru'admin'>]
<Useru'admin'>
app.py
fromdatabaseimportdb_session,init_db
frommodelsimportUser
fromflaskimportFlask
#------------------------------------------
app=Flask(__name__)
#------------------------------------------
@app.teardown_appcontext
defshutdown_session(exception=None):
db_session.remove()
#------------------------------------------
init_db()
u=User('admin','admin@localhost')
db_session.add(u)
db_session.commit()
printUser.query.all()
printUser.query.filter(User.name=='admin').first()
14 / 20
Manual Object Relational Mapping
 
15 / 20
Example #7
database.py
fromsqlalchemyimportcreate_engine
fromsqlalchemy.ormimportscoped_session,sessionmaker
#fromsqlalchemy.ext.declarativeimportdeclarative_base
fromsqlalchemyimportMetaData
#------------------------------------------
engine=create_engine('sqlite:///test.db',convert_unicode=
db_session=scoped_session(sessionmaker(autocommit=False,
autoflush=False,
bind=engine))
metadata=MetaData()
#Base=declarative_base()
#Base.query=db_session.query_property()
#------------------------------------------
definit_db():
#importmodels
#Base.metadata.create_all(bind=engine)
metadata.create_all(bind=engine)
models.py
fromsqlalchemyimportColumn,Integer,String
#fromdatabaseimportBase
fromsqlalchemyimportTable
fromsqlalchemy.ormimportmapper
fromdatabaseimportmetadata,db_session
#------------------------------------------
#classUser(Base):
classUser(object):
#__tablename__='users'
#id=Column(Integer,primary_key=True)
#name=Column(String(50),unique=True)
#email=Column(String(120),unique=True)
query=db_session.query_property()
def__init__(self,name=None,email=None):
self.name=name
self.email=email
def__repr__(self):
return'<User%r>'%(self.name)
#------------------------------------------
users=Table('users',metadata,
Column('id',Integer,primary_key=True),
Column('name',String(50),unique=True),
Column('email',String(120),unique=True)
)
mapper(User,users)
16 / 20
SQL Abstraction Layer
 
17 / 20
fromsqlalchemyimportcreate_engine,MetaData
fromsqlalchemyimportTable,Column,Integer,String
engine=create_engine('sqlite:///test.db',convert_unicode=
metadata=MetaData(bind=engine)
users=Table('users',metadata,
Column('id',Integer,primary_key=True),
Column('name',String(50),unique=True),
Column('email',String(120),unique=True)
)
metadata.create_all(bind=engine)
#users=Table('users',metadata,autoload=True)
#ifpreviouslyexists
con=engine.connect()
con.execute(users.insert(),name='admin',email='admin@localhost'
#SQLAlchemywillautomaticallycommitforus.
printusers.select(users.c.id==1).execute().first()
r=users.select(users.c.id==1).execute().first()
print r['name']
printengine.execute('select*fromuserswhereid=:1',[1
Example #8
(1,u'admin',u'admin@localhost')
admin
(1,u'admin',u'admin@localhost')
18 / 20
References
Flask-SQLAlchemy Documentation
SQLAlchemy Documentation
Patterns for Flask - Flask Documentation
Patterns - SQLAlchemy in Flask
19 / 20

END
Eueung Mulyana
http://eueung.github.io/python/flask-sqlalchemy
Python CodeLabs | Attribution-ShareAlike CC BY-SA
20 / 20

Flask SQLAlchemy