Introduction to SQLAlchemy and Alembic Migrations
Click here to load reader
-
Upload
jason-myers -
Category
Technology
-
view
163 -
download
0
description
Transcript of Introduction to SQLAlchemy and Alembic Migrations
![Page 1: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/1.jpg)
SQLAlchemy andAlembic
ORM, Core and Migrations / Jason Myers @jasonamyers
![Page 2: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/2.jpg)
![Page 3: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/3.jpg)
Architecture
![Page 4: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/4.jpg)
![Page 5: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/5.jpg)
pip install sqlalchemy
pip install flask-sqlalchemy
bin/paster create -t pyramid_alchemy tutorial
![Page 6: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/6.jpg)
from sqlalchemy import create_engineengine = create_engine( ‘dialect+driver://USER:PASS@HOST:PORT/DB’)
![Page 7: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/7.jpg)
Porcelain
![Page 8: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/8.jpg)
![Page 9: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/9.jpg)
from sqlalchemy.ext.declarative import ( declarative_base)
Base = declarative_base()
![Page 10: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/10.jpg)
![Page 11: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/11.jpg)
from sqlalchemy import ( Column, Integer, String, Float)from sqlalchemy import ForeignKeyfrom sqlalchemy.orm import ( relationship, backref)
![Page 12: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/12.jpg)
class User(Base): __tablename__ = 'users' id = Column(Integer, primary_key=True) name = Column(String) fullname = Column(String) balance = Column(Float) group = Column(String) addresses = relationship( "Address", order_by="Address.id", backref="user" )
![Page 13: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/13.jpg)
def __init__(self, name, fullname, balance, group): self.name = name self.fullname = fullname self.balance = balance self.group = group
![Page 14: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/14.jpg)
![Page 15: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/15.jpg)
Base.metadata.create_all(engine)
![Page 16: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/16.jpg)
![Page 17: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/17.jpg)
from sqlalchemy.orm import sessionmakerSession = sessionmaker(bind=engine)db = Session()
![Page 18: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/18.jpg)
user1 = User('Bob', 'Big Bob', 1000000.00, 'Mob')user2 = User('Linda', 'Linda Lu', 100.50, 'Diner')user3 = User('Lil Bob', 'Bobby Jr', 100500.00, 'Mob')user4 = User('Rachael', 'Rachael Rach', 125.50, 'Personal')
![Page 19: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/19.jpg)
db.add(user1)
db.commit()
db.delete(user1)
![Page 20: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/20.jpg)
db.expunge(user1)
db.refresh(user1)db.expire(user1)
db.rollback()
![Page 21: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/21.jpg)
![Page 22: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/22.jpg)
for user in db.query(User).all(): print user.name, user.balance
Out[1]: Bob 1000000.0
![Page 23: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/23.jpg)
entries = db.session.query(Entries).filter_by(user_id=user.id)\ .filter(Entries.entry_time > (datetime.datetime.utcnow() - datetime.timedelta(30))).order_by('ID DESC').all()
![Page 24: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/24.jpg)
SELECT entries.id AS entries_id, entries.user_id AS entries_user_id, entries.phone AS entries_phone, entries.measurement AS entries_measurement, entries.insulin AS entries_insulin, entries.insulin_type AS entries_insulin_type, entries.carbs AS entries_carbs, entries.tag AS entries_tag, entries.three_sixty_id AS entries_three_sixty_id, entries.entry_time AS entries_entry_time, entries.created_time AS entries_created_timeFROM entriesWHERE entries.user_id = :user_id_1 AND entries.entry_time > :entry_time_1ORDER BY ID DESC
![Page 25: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/25.jpg)
from sqlalchemy import funcfrom sqlalchemy.sql import labelresults = db.query( User.group, label('members', func.count(User.id)), label( 'total_balance', func.sum(User.balance) )).group_by(User.group).all()for result in results: print result.group, result.members, result.total_balance
![Page 26: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/26.jpg)
![Page 27: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/27.jpg)
bob.addresses.append(home_address)
bob.addresses
bob.addresses.filter(Address.type='H').one()
![Page 28: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/28.jpg)
query = db.query(User, Address).filter(User.id==Address.user_id)query = query.filter(Address.email_address=='[email protected]').all()
![Page 29: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/29.jpg)
![Page 30: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/30.jpg)
@hybrid_propertydef grand_total(self): rollup_fields = [ 'merchandise_cost', 'tax', 'shipping', ] total = sum([self.__getattribute__(x) for x in rollup_fields]) return round(total, 2)
![Page 31: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/31.jpg)
![Page 32: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/32.jpg)
Plumbing
![Page 33: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/33.jpg)
from sqlalchemy import create_engineengine = create_engine( ‘dialect+driver://USER:PASS@HOST:PORT/DB’)
![Page 34: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/34.jpg)
from sqlalchemy import (Table, Column, Integer, String, MetaData, ForeignKey)metadata = MetaData()users = Table('users', metadata, Column('id', Integer, primary_key=True), Column('name', String), Column('fullname', String),)
![Page 35: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/35.jpg)
Base.metadata.create_all(engine)conn = engine.connect()
![Page 36: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/36.jpg)
ins = users.insert().values(name='jack', fullname='Jack Bell')result = conn.execute(ins)
ins = users.insert()conn.execute(ins, id=2, name='wendy', fullname='Wendy McDonalds')
![Page 37: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/37.jpg)
conn.execute(addresses.insert(), [ {'user_id': 1, 'email_address' : '[email protected]'}, {'user_id': 1, 'email_address' : '[email protected]'},])
![Page 38: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/38.jpg)
def build_table(table_name):return Table( table_name, metadata, autoload=True, autoload_with=engine)
![Page 39: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/39.jpg)
build_table('census')unavailable_fields = [ c.name for c in t.c if isinstance(c.type, NullType)]
![Page 40: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/40.jpg)
![Page 41: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/41.jpg)
InformixMS SQLOraclePostgresSQLiteCustom
![Page 42: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/42.jpg)
class UnloadFromSelect(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)def visit_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 ',' addquotes allowoverwrite" % { 'query': compiler.process(element.select, unload_select=True, literal_binds=True), 'bucket': element.bucket, 'access_key': element.access_key, 'secret_key': element.secret_key, }
![Page 43: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/43.jpg)
unload = UnloadFromSelect( select([fields]), '/'.join(['s3:/', BUCKET, filename]), ACCESS_KEY, SECRET_KEY)
![Page 44: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/44.jpg)
unload ( 'select * from venue where venueid in ( select venueid from venue order by venueid desc limit 10)')to 's3://mybucket/venue_pipe_'credentials 'aws_access_key_id=ACCESS_KEY; aws_secret_access_key=SECRET_KEY';
![Page 45: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/45.jpg)
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)
![Page 46: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/46.jpg)
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' not in unavailable_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('discharges DESC')
cases = conn.execute(s).fetchall()
![Page 47: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/47.jpg)
![Page 48: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/48.jpg)
pip install alembic
![Page 49: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/49.jpg)
alembic init alembic
![Page 50: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/50.jpg)
![Page 51: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/51.jpg)
![Page 52: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/52.jpg)
# A generic, single database configuration.[alembic]# path to migration scriptsscript_location = alembic# template used to generate migration files# file_template = %%(rev)s_%%(slug)s# set to 'true' to run the environment during# the 'revision' command, regardless ofautogenerate# revision_environment = falsesqlalchemy.url = driver://user:pass@localhost/dbname
![Page 53: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/53.jpg)
from glu import dbtarget_metadata = db.metadatadef run_migrations_online(): alembic_config = config.get_section(config.config_ini_section) from config import SQLALCHEMY_DATABASE_URI alembic_config['sqlalchemy.url'] = SQLALCHEMY_DATABASE_URI engine = engine_from_config( alembic_config, prefix='sqlalchemy.', poolclass=pool.NullPool)
![Page 54: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/54.jpg)
![Page 55: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/55.jpg)
alembic revision -m "initial"
![Page 56: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/56.jpg)
def upgrade(): op.create_table('users_to_users', sa.Column('patient_user_id', sa.Integer(), nullable=False), sa.Column('provider_user_id', sa.Integer(), nullable=False), sa.ForeignKeyConstraint(['patient_user_id'], ['users.id'],), sa.ForeignKeyConstraint(['provider_user_id'], ['users.id'],), sa.PrimaryKeyConstraint('patient_user_id','provider_user_id') )
op.alter_column(u'reminders', u'user_created', nullable=True)
![Page 57: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/57.jpg)
def downgrade(): op.alter_column(u'reminders', u'user_created', existing_type=mysql.TINYINT(display_width=1), nullable=False ) op.drop_table('users_to_users')
![Page 58: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/58.jpg)
alembic upgrade head
![Page 59: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/59.jpg)
alembic revision --autogenerate -m "Added account table"
![Page 60: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/60.jpg)
Table (adds/removes)Columns (adds/removes)Nullable changes
![Page 61: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/61.jpg)
![Page 62: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/62.jpg)
Optionally: Column Type changescompare_type=TrueNo Name changes on Columns or Table
![Page 63: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/63.jpg)
![Page 64: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/64.jpg)
alembic currentalembic upgrade +2alembic downgrade -1alembic upgrade ae1alembic upgrade 1 --sql > file.sqlalembic history
![Page 65: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/65.jpg)
2806761df139 -> 1e9831c8fa7d (head), Adding tags to ...2806761df139 -> 46a1d4de6e04 (head), Added timezone ...4f7119855daf -> 2806761df139 (branchpoint), Added Pr...377addf23edb -> 4f7119855daf, Added user_created to ...483d9a63fbf5 -> 377addf23edb, Adding claimed to user...464ba41d7ad8 -> 483d9a63fbf5, Adding username/passwo...2cfd9dc89267 -> 464ba41d7ad8, Adding Intercom.iod4774a3ce8 -> 2cfd9dc89267, Seperating Roles and Use...None -> d4774a3ce8, Base
![Page 66: Introduction to SQLAlchemy and Alembic Migrations](https://reader037.fdocuments.net/reader037/viewer/2022100217/54c6b8644a7959a6418b45a0/html5/thumbnails/66.jpg)
THE END@jasonamyers