Created by Jason A Myers / @jasonamyers
pip install sqlalchemy
from sqlalchemy import create_engine engine = create_engine('sqlite:///:memory:')
from sqlalchemy.orm import sessionmaker Session = sessionmaker(bind=engine) session = Session()The session is the way SQLAlchemy ORM interacts with the database. It wraps a database connection via an engine, and provides an identity map for objects that you load via the session or associate with the session. The identity map is a cache like data structure that contains a unique list of objects determined by the object’s table and primary key. A session also wraps a transaction, and that transaction will be open until the Session is committed or rolled back
Declarative Base
from sqlalchemy.ext.declarative import declarative_base Base = declarative_base()
from sqlalchemy import Column, Integer, Numeric, String class Cookie(Base): __tablename__ = 'cookies' cookie_id = Column(Integer, primary_key=True) cookie_name = Column(String(50), index=True) cookie_recipe_url = Column(String(255)) cookie_sku = Column(String(55)) quantity = Column(Integer()) unit_cost = Column(Numeric(12, 2))Inherit from the declarative_base Contain __tablename__ Contain 1+ columns Have a primary key
Base.metadata.create_all(engine)
cc_cookie = Cookie(cookie_name='chocolate chip', cookie_recipe_url='http://some.aweso.me/cookie/recipe.html', cookie_sku='CC01', quantity=12, unit_cost=0.50)
session.add(cc_cookie) session.commit()
INFO:sqlalchemy.engine.base.Engine:BEGIN (implicit) INFO:sqlalchemy.engine.base.Engine:INSERT INTO cookies (cookie_name, cookie_recipe_url, cookie_sku, quantity, unit_cost) VALUES (?, ?, ?, ?, ?) INFO:sqlalchemy.engine.base.Engine:('chocolate chip', 'http://some.aweso.me/cookie/recipe.html', 'CC01', 12, 0.5) INFO:sqlalchemy.engine.base.Engine:COMMIT
print(cc_cookie.cookie_id) 1
c1 = Cookie(cookie_name='peanut butter', cookie_recipe_url='http://some.aweso.me/cookie/peanut.html', cookie_sku='PB01', quantity=24, unit_cost=0.25) c2 = Cookie(cookie_name='oatmeal raisin', cookie_recipe_url='http://some.okay.me/cookie/raisin.html', cookie_sku='EWW01', quantity=100, unit_cost=1.00) session.bulk_save_objects([c1,c2]) session.commit()
c1.cookie_idSpeed with tradeoff - Relationships are not respected - Objects are not connected to the session - Primary Keys not fetched - No events triggered
cookies = session.query(Cookie).all() print(cookies) [Cookie(cookie_name='chocolate chip', cookie_recipe_url='http://some.aweso.me/cookie/recipe.html', cookie_sku='CC01', quantity=12, unit_cost=0.50), Cookie(cookie_name='peanut butter', cookie_recipe_url='http://some.aweso.me/cookie/peanut.html', cookie_sku='PB01', quantity=24, unit_cost=0.25), Cookie(cookie_name='oatmeal raisin', cookie_recipe_url='http://some.okay.me/cookie/raisin.html', cookie_sku='EWW01', quantity=100, unit_cost=1.00)]
for cookie in session.query(Cookie): print(cookie) Cookie(cookie_name='chocolate chip', cookie_recipe_url='http://some.aweso.me/cookie/recipe.html', cookie_sku='CC01', quantity=12, unit_cost=0.50) Cookie(cookie_name='peanut butter', cookie_recipe_url='http://some.aweso.me/cookie/peanut.html', cookie_sku='PB01', quantity=24, unit_cost=0.25) Cookie(cookie_name='oatmeal raisin', cookie_recipe_url='http://some.okay.me/cookie/raisin.html', cookie_sku='EWW01', quantity=100, unit_cost=1.00)
print(session.query(Cookie.cookie_name, Cookie.quantity).first()) ('chocolate chip', 12)
for cookie in session.query(Cookie).order_by(Cookie.quantity): print('{:3} - {}'.format(cookie.quantity, cookie.cookie_name)) 12 - chocolate chip 24 - peanut butter 100 - oatmeal raisin
from sqlalchemy import desc for cookie in session.query(Cookie).order_by(desc(Cookie.quantity)): print('{:3} - {}'.format(cookie.quantity, cookie.cookie_name))
query = session.query(Cookie).order_by(Cookie.quantity).limit(2) print([result.cookie_name for result in query]) ['chocolate chip', 'peanut butter']
from sqlalchemy import func inv_count = session.query(func.sum(Cookie.quantity)).scalar() print(inv_count) 136Returns the first element of the first result, None if there is no result, or an error if there is more than one result.
rec_count = session.query(func.count(Cookie.cookie_name)).first() print(rec_count) (3, 0)
rec_count = session.query(func.count(Cookie.cookie_name) \ .label('inventory_count')).first() print(rec_count.keys()) print(rec_count.inventory_count) ['inventory_count'] 5
record = session.query(Cookie). \ filter_by(cookie_name='chocolate chip').first() print(record) Cookie(cookie_name='chocolate chip', cookie_recipe_url='http://some.aweso.me/cookie/recipe.html', cookie_sku='CC01', quantity=12, unit_cost=0.50)
record = session.query(Cookie). \ filter(Cookie.cookie_name == 'chocolate chip').first() print(record)
query = session.query(Cookie).filter( Cookie.cookie_name.like('%chocolate%')) for record in query: print(record.cookie_name) chocolate chipClauseElements are just an entity we use in a clause, and they are typically columns in a table; however, unlike columns, ClauseElements come with many additional capabil‐ ities.
from sqlalchemy import cast query = session.query(Cookie.cookie_name, cast((Cookie.quantity * Cookie.unit_cost), Numeric(12,2)).label('inv_cost')) for result in query: print('{} - {}'.format(result.cookie_name, result.inv_cost)) chocolate chip - 6.00 peanut butter - 6.00 oatmeal raisin - 100.00
from sqlalchemy import and_, or_, not_ query = session.query(Cookie).filter( or_( Cookie.quantity.between(10, 50), Cookie.cookie_name.contains('chip') ) ) for result in query: print(result.cookie_name) chocolate chip peanut butter
query = session.query(Cookie) cc_cookie = query.filter(Cookie.cookie_name == "chocolate chip").first() cc_cookie.quantity = cc_cookie.quantity + 120 session.commit() print(cc_cookie.quantity) 132
query = session.query(Cookie) query = query.filter(Cookie.cookie_name == "peanut butter") dcc_cookie = query.one() session.delete(dcc_cookie) session.commit() dcc_cookie = query.first() print(dcc_cookie) Nonequeries all the rows, and raises an exception if anything other than a single result is returned
from datetime import datetime from sqlalchemy import DateTime, ForeignKey, Boolean from sqlalchemy.orm import relationship, backref
class User(Base): __tablename__ = 'users' user_id = Column(Integer(), primary_key=True) username = Column(String(15), nullable=False, unique=True) email_address = Column(String(255), nullable=False) phone = Column(String(20), nullable=False) password = Column(String(25), nullable=False) created_on = Column(DateTime(), default=datetime.now) updated_on = Column(DateTime(), default=datetime.now, onupdate=datetime.now)
class Order(Base): __tablename__ = 'orders' order_id = Column(Integer(), primary_key=True) user_id = Column(Integer(), ForeignKey('users.user_id')) shipped = Column(Boolean(), default=False) user = relationship("User", backref=backref('orders', order_by=order_id))
class LineItem(Base): __tablename__ = 'line_items' line_item_id = Column(Integer(), primary_key=True) order_id = Column(Integer(), ForeignKey('orders.order_id')) cookie_id = Column(Integer(), ForeignKey('cookies.cookie_id')) quantity = Column(Integer()) extended_cost = Column(Numeric(12, 2)) order = relationship("Order", backref=backref('line_items', order_by=line_item_id)) cookie = relationship("Cookie", uselist=False)
Base.metadata.create_all(engine)
cookiemon = User(username='cookiemon', email_address='mon@cookie.com', phone='111-111-1111', password='password') session.add(cookiemon) session.commit()
o1 = Order() o1.user = cookiemon session.add(o1)
cc = session.query(Cookie).filter(Cookie.cookie_name == "chocolate chip").one() line1 = LineItem(cookie=cc, quantity=2, extended_cost=1.00) pb = session.query(Cookie).filter(Cookie.cookie_name == "oatmeal raisin").one() line2 = LineItem(quantity=12, extended_cost=3.00) line2.cookie = pb
o1.line_items.append(line1) o1.line_items.append(line2) session.commit()
query = session.query(Order.order_id, User.username, User.phone, Cookie.cookie_name, LineItem.quantity, LineItem.extended_cost) query = query.join(User).join(LineItem).join(Cookie) results = query.filter(User.username == 'cookiemon').all() print(results) [(1, 'cookiemon', '111-111-1111', 'chocolate chip', 2, Decimal('1.00')), (1, 'cookiemon', '111-111-1111', 'oatmeal raisin', 12, Decimal('3.00'))]
query = session.query(User.username, func.count(Order.order_id)) query = query.outerjoin(Order).group_by(User.username) for row in query: print(row) ('cookiemon', 1)
Jason Myers / @jasonamyers / Essential SQLAlchemy http://bit.ly/jam-sqlalchemy-orm