Your SlideShare is downloading. ×
0
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Introduction to SQLAlchemy and Alembic Migrations
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

Introduction to SQLAlchemy and Alembic Migrations

3,232

Published on

In this talk, we'll examine how to use SQLAlchemy ORM and Core in both simple queries and query builder type applications. Next, we'll explore Alembic database migrations and how we can use them to …

In this talk, we'll examine how to use SQLAlchemy ORM and Core in both simple queries and query builder type applications. Next, we'll explore Alembic database migrations and how we can use them to handle database changes.

Published in: Technology, Business
0 Comments
6 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
3,232
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
48
Comments
0
Likes
6
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. SQLAlchemy and Alembic ORM, Core and Migrations /Jason Myers @jasonamyers
  • 2. Architecture
  • 3. pip install sqlalchemy pip install flask-sqlalchemy bin/paster create -t pyramid_alchemy tutorial
  • 4. from sqlalchemy import create_engine engine = create_engine( ‘dialect+driver://USER:PASS@HOST:PORT/DB’ )
  • 5. Porcelain
  • 6. from sqlalchemy.ext.declarative import ( declarative_base ) Base = declarative_base()
  • 7. from sqlalchemy import ( Column,
 Integer, String, Float ) from sqlalchemy import ForeignKey from sqlalchemy.orm import ( relationship, backref )
  • 8. 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" )
  • 9. def __init__(self, name, fullname, balance, group): self.name = name self.fullname = fullname self.balance = balance self.group = group
  • 10. Base.metadata.create_all(engine)
  • 11. from sqlalchemy.orm import sessionmaker Session = sessionmaker(bind=engine) db = Session()
  • 12. 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')
  • 13. db.add(user1) db.commit() db.delete(user1)
  • 14. db.expunge(user1) db.refresh(user1) db.expire(user1) db.rollback()
  • 15. for user in db.query(User).all(): print user.name, user.balance Out[1]: Bob 1000000.0
  • 16. 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()
  • 17. 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_time FROM entries WHERE entries.user_id = :user_id_1 AND entries.entry_time > :entry_time_1 ORDER BY ID DESC
  • 18. from sqlalchemy import func from sqlalchemy.sql import label results = 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
  • 19. bob.addresses.append(home_address) bob.addresses bob.addresses.filter(Address.type='H').one()
  • 20. query = db.query(User, Address).filter(User.id==Address.user_id) query = query.filter(Address.email_address=='jack@goog.com').all()
  • 21. @hybrid_property def grand_total(self): rollup_fields = [ 'merchandise_cost', 'tax', 'shipping', ] total = sum([self.__getattribute__(x) for x in rollup_fields]) return round(total, 2)
  • 22. Plumbing
  • 23. from sqlalchemy import create_engine engine = create_engine( ‘dialect+driver://USER:PASS@HOST:PORT/DB’ )
  • 24. 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), )
  • 25. Base.metadata.create_all(engine) conn = engine.connect()
  • 26. 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')
  • 27. conn.execute(addresses.insert(), [ {'user_id': 1, 'email_address' : 'j@y.com'}, {'user_id': 1, 'email_address' : 'j@m.com'}, ])
  • 28. def build_table(table_name): return Table( table_name, metadata, autoload=True, autoload_with=engine )
  • 29. build_table('census') unavailable_fields = [ c.name for c in t.c if isinstance(c.type, NullType) ]
  • 30. Informix MS SQL Oracle Postgres SQLite Custom
  • 31. 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, }
  • 32. unload = UnloadFromSelect( select([fields]), '/'.join(['s3:/', BUCKET, filename]), ACCESS_KEY, SECRET_KEY )
  • 33. 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';
  • 34. 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)
  • 35. 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()
  • 36. pip install alembic
  • 37. alembic init alembic
  • 38. # A generic, single database configuration. [alembic] # path to migration scripts script_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 of autogenerate # revision_environment = false sqlalchemy.url = driver://user:pass@localhost/dbname
  • 39. from glu import db target_metadata = db.metadata def 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 )
  • 40. alembic revision -m "initial"
  • 41. 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)
  • 42. 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')
  • 43. alembic upgrade head
  • 44. alembic revision --autogenerate -m "Added account table"
  • 45. Table (adds/removes) Columns (adds/removes) Nullable changes
  • 46. Optionally: Column Type changes compare_type=True No Name changes on Columns or Table
  • 47. alembic current alembic upgrade +2 alembic downgrade -1 alembic upgrade ae1 alembic upgrade 1 --sql > file.sql alembic history
  • 48. 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.io d4774a3ce8 -> 2cfd9dc89267, Seperating Roles and Use... None -> d4774a3ce8, Base
  • 49. THE END @jasonamyers

×