examples.performance.short_selects
优质
小牛编辑
133浏览
2023-12-01
"""This series of tests illustrates different ways to SELECT a single record by primary key """ import random from sqlalchemy import bindparam from sqlalchemy import Column from sqlalchemy import create_engine from sqlalchemy import Integer from sqlalchemy import select from sqlalchemy import String from sqlalchemy.ext import baked from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.future import select as future_select from sqlalchemy.orm import deferred from sqlalchemy.orm import Session from sqlalchemy.sql import lambdas from . import Profiler Base = declarative_base() engine = None ids = range(1, 11000) class Customer(Base): __tablename__ = "customer" id = Column(Integer, primary_key=True) name = Column(String(255)) description = Column(String(255)) q = Column(Integer) p = Column(Integer) x = deferred(Column(Integer)) y = deferred(Column(Integer)) z = deferred(Column(Integer)) Profiler.init("short_selects", num=10000) @Profiler.setup def setup_database(dburl, echo, num): global engine engine = create_engine(dburl, echo=echo) Base.metadata.drop_all(engine) Base.metadata.create_all(engine) sess = Session(engine) sess.add_all( [ Customer( id=i, name="c%d" % i, description="c%d" % i, q=i * 10, p=i * 20, x=i * 30, y=i * 40, ) for i in ids ] ) sess.commit() @Profiler.profile def test_orm_query_classic_style(n): """classic ORM query of the full entity.""" session = Session(bind=engine) for id_ in random.sample(ids, n): session.query(Customer).filter(Customer.id == id_).one() @Profiler.profile def test_orm_query_new_style(n): """new style ORM select() of the full entity.""" session = Session(bind=engine) for id_ in random.sample(ids, n): stmt = future_select(Customer).where(Customer.id == id_) session.execute(stmt).scalar_one() @Profiler.profile def test_orm_query_new_style_using_embedded_lambdas(n): """new style ORM select() of the full entity w/ embedded lambdas.""" session = Session(bind=engine) for id_ in random.sample(ids, n): stmt = future_select(lambda: Customer).where( lambda: Customer.id == id_ ) session.execute(stmt).scalar_one() @Profiler.profile def test_orm_query_new_style_using_external_lambdas(n): """new style ORM select() of the full entity w/ external lambdas.""" session = Session(bind=engine) for id_ in random.sample(ids, n): stmt = lambdas.lambda_stmt(lambda: future_select(Customer)) stmt += lambda s: s.where(Customer.id == id_) session.execute(stmt).scalar_one() @Profiler.profile def test_orm_query_classic_style_cols_only(n): """classic ORM query against columns""" session = Session(bind=engine) for id_ in random.sample(ids, n): session.query(Customer.id, Customer.name, Customer.description).filter( Customer.id == id_ ).one() @Profiler.profile def test_orm_query_new_style_ext_lambdas_cols_only(n): """new style ORM query w/ external lambdas against columns.""" s = Session(bind=engine) for id_ in random.sample(ids, n): stmt = lambdas.lambda_stmt( lambda: future_select( Customer.id, Customer.name, Customer.description ) ) + (lambda s: s.filter(Customer.id == id_)) s.execute(stmt).one() @Profiler.profile def test_baked_query(n): """test a baked query of the full entity.""" bakery = baked.bakery() s = Session(bind=engine) for id_ in random.sample(ids, n): q = bakery(lambda s: s.query(Customer)) q += lambda q: q.filter(Customer.id == bindparam("id")) q(s).params(id=id_).one() @Profiler.profile def test_baked_query_cols_only(n): """test a baked query of only the entity columns.""" bakery = baked.bakery() s = Session(bind=engine) for id_ in random.sample(ids, n): q = bakery( lambda s: s.query(Customer.id, Customer.name, Customer.description) ) q += lambda q: q.filter(Customer.id == bindparam("id")) q(s).params(id=id_).one() @Profiler.profile def test_core_new_stmt_each_time(n): """test core, creating a new statement each time.""" with engine.connect() as conn: for id_ in random.sample(ids, n): stmt = select(Customer.__table__).where(Customer.id == id_) row = conn.execute(stmt).first() tuple(row) @Profiler.profile def test_core_new_stmt_each_time_compiled_cache(n): """test core, creating a new statement each time, but using the cache.""" compiled_cache = {} with engine.connect().execution_options( compiled_cache=compiled_cache ) as conn: for id_ in random.sample(ids, n): stmt = select(Customer.__table__).where(Customer.id == id_) row = conn.execute(stmt).first() tuple(row) @Profiler.profile def test_core_reuse_stmt(n): """test core, reusing the same statement (but recompiling each time).""" stmt = select(Customer.__table__).where(Customer.id == bindparam("id")) with engine.connect() as conn: for id_ in random.sample(ids, n): row = conn.execute(stmt, id=id_).first() tuple(row) @Profiler.profile def test_core_reuse_stmt_compiled_cache(n): """test core, reusing the same statement + compiled cache.""" stmt = select(Customer.__table__).where(Customer.id == bindparam("id")) compiled_cache = {} with engine.connect().execution_options( compiled_cache=compiled_cache ) as conn: for id_ in random.sample(ids, n): row = conn.execute(stmt, id=id_).first() tuple(row) if __name__ == "__main__": Profiler.main()