from sqlalchemy import create_engine
engine = create_engine('postgresql://username:password@host:port/table')
DATABASES
dict, just one database URLdj-database-url
does the same for Django
connection = engine.connect(); connection.execute(...)
create_engine(..., pool_size=..., max_overflow=...)
first = create_engine(...); second =
create_engine(...);
connection = engine.connect()
result = connection.execute('SELECT username FROM users;')
usernames = [row['username'] for row in result]
connection.close()
import sqlalchemy as sa
metadata = sa.MetaData()
users = sa.Table('users', metadata,
sa.Column('id', sa.Integer, primary_key=True),
sa.Column('username', sa.String(64), unique=True),
...
)
metadata.create_all(engine)
metadata.reflect(engine)
users = metadata.tables['users']
connection = engine.connect()
ins = users.insert().values(username='johndoe')
connection.execute(ins)
connection.execute(users.insert(), username='janedoe')
connection.execute(users.insert(), [
{'username': 'gepa'},
{'username': 'dopa'},
{'username': 'ptnpnh'},
])
connection.close()
from sqlalchemy.sql import select
connection = engine.connect()
result = connection.execute(select([users]))
usernames = [row['username'] for row in result]
result.close()
query = select([users]).where(users.c.username == 'johndoe')
result = connection.execute(query)
username = result.fetchone()
result.close()
users.c.username == 'johndoe'
users.c.username != 'johndoe'
users.c.username.contains('doe')
~users.c.username.contains('doe')
users.c.username.like('doe')
users.c.username.match('doe$')
users.c.username.startswith('j')
users.c.username.endswith('doe')
from sqlalchemy.sql import and_, or_, not_
users.c.username.like('%doe') & (users.c.id > 2)
and_(users.c.username.like('%doe'), users.c.id > 2)
users.c.username.like('%doe') | ~(users.c.id < 2)
or_(users.c.username.like('%doe'), not_(users.c.id < 2))
select([users]).where(...).where(...)
select([users]).where(or_(...))
u1 = users.alias()
u2 = users.alias()
(u1.username == 'johndoe') & (u2.username == 'janedoe')
from sqlalchemy.sql import text
query = text(
'SELECT username '
'FROM users '
'WHERE username LIKE :like AND id < :threshold'
)
result = connection.execute(query, like='%doe', threshold=3)
users.join(orders)
select([users.c.username]).select_from(
users.join(
orders,
orders.c.price > 50
)
)
select([users.c.username]).select_from(users.outerjoin(orders))
from sqlalchemy import Column, String
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class Country(Base):
"""
Country model.
"""
__tablename__ = 'countries'
code = Column(String(2), primary_key=True)
name = Column(String(64), unique=True)
from sqlalchemy import ForeignKey, Integer, Numeric
from sqlalchemy.orm import backref, relationship
class City(Base):
"""
City model.
"""
__tablename__ = 'orders'
id = Column(Integer, primary_key=True)
country_code = Column(String(2), ForeignKey('countries.code'))
name = Column(String(128))
country = relationship(
'Country', backref=backref('cities', lazy='dynamic')
)
class Airport(Base):
"""
Airport model.
"""
__tablename__ = 'airports'
id = Column(Integer, primary_key=True)
city_id = Column(Integer, ForeignKey('cities.id'))
main_city_id = Column(Integer, ForeignKey('cities.id'), nullable=True)
...
city = relationship('City',
backref=backref('airports', lazy='dynamic'),
foreign_keys=[city_id])
main_city = relationship(
'City',
backref=backref('closest_airports', lazy='dynamic'),
foreign_keys=[main_city_id]
)
class Flight(Base):
"""
Flight model.
"""
__tablename__ = 'flights'
id = Column(Integer, primary_key=True)
back_flight_id = Column(Integer, ForeignKey('flights.id'), nullable=True)
...
back_flight = relationship('Flight')
class Point(object):
"""
Simple geo point.
"""
__slots__ = ('latitude', 'longitude')
def __init__(self, latitude, longitude):
self.latitude, self.longitude = latitude, longitude
def __composite_fields__(self):
return (self.latitude, self.longitude)
def __eq__(self, other):
if not isinstance(other, Point):
return False
return (
self.latitude == other.latitude and
self.longitude == other.longitude
)
def __repr__(self):
return 'Point({0:.4f}, {1:.4f})'.format(self.latitude, self.longitude)
from sqlalchemy import Numeric
from sqlalchemy.orm import composite
class Airport(Base):
...
latitude = Column(Numeric(6, 4, True))
longitude = Column(Numeric(6, 4, True))
point = composite(Point, latitude, longitude)
categories_m2m = Table(
'categories_m2m',
Base.metadata,
Column('category_id', Integer, ForeignKey('categories.id')),
Column('post_id', Integer, ForeignKey('posts.id')).
)
class Category(Base):
...
class Post(Base):
...
categories = relationship('Category',
backref=backref('posts', lazy='dynamic'),
secondary=categories_m2m)
engine = create_engine(DATABASE_URL)
for model in (Airport, City, Country, Flight):
model.metadata.bind = engine
model.metadata.create_all()
from sqlalchemy.orm import sessionmaker
engine = create_engine(DATABASE_URL)
Session = sessionmaker(engine)
session = Session()
# Add (create) objects to database
session.add(Country(code='UA', name='Ukraine'))
session.add_all([
Country(code='GB', name='Great Britain'),
Country(code='US', name='United States of America')
])
# Commit changes to database
session.commit()
# Perform queries
ua = session.query(Country).filter_by(code='UA').first()
session.query(Country).filter(Country.code.in_(['GB', 'US']).all()
# Update object
ua.name = 'Viva la Ukraine'
# Apply change
session.commit()
# Or revert change
session.rollback()
# Delete object
gb = session.query(Country).filter(Country.code == 'GB').first()
session.delete(gb)
# Don't forget to commit session
session.commit()
from sqlalchemy import func
from sqlalchemy.orm.exc import NoResultFound
counter = session.query(func.count(Country.code)).scalar()
ua = session.query(Country).get('UA')
session.query(Country.name).filter(Country.code.in_(['GB', 'UA', 'US'])).all()
session.query(Airport).filter(Airport.iata.like('K%')).all()
kbp = session.query(Airport).filter(Airport.iata == 'KBP').first()
try:
session.query(Airport).filter(Airport.iata == 'XXX').one()
except NoResultFound:
...
session.query(Airport).filter(Airport.main_city_id != None)
ua = session.query(Country).get('UA')
ua.cities.all()
ua.cities.filter(City.name.in_([
'Kyiv', 'Kharkiv', 'Lviv', 'Odesa', 'Dnipropetrivsk', 'Donetsk'
])
kyiv = (session.query(City)
.join(Country)
.filter((City.name == 'Kyiv') & (Country.code == 'UA'))
.first())
kyiv.airports.all()
kyiv.closest_airports.all()
session.query(City).join(Country).filter(Country.code == 'UA').all()
session.query(Airport, City).join(City, Airport.city_id == City.id).all()
from collections import defaultdict
from sqlalchemy.orm import joinedload
closest_cities = defaultdict(set)
query = (session.query(City, Airport)
.options(joinedload(Airport.city))
.join(Airport, City.id == Airport.main_city_id))
for city, airport in query.all():
closest_cities[city.name].add(airport.city.name)
from contextlib import contextmanager
from sqlalchemy.exc import SQLAlchemyError
@contextmanager
def session():
session = Session()
try:
yield session
session.commit()
except SQLAlchemyError:
session.rollback()
raise
finally:
session.close()