Files
sqlalchemy/test/aaa_profiling/test_misc.py
T
Mike Bayer 01c50c64e3 Remove all remaining removed_in_20 warnings slated for removal
Finalize all remaining removed-in-2.0 changes so that we
can begin doing pep-484 typing without old things
getting in the way (we will also have to do public_factory).

note there are a few "moved_in_20()" and "became_legacy_in_20()"
warnings still in place.  The SQLALCHEMY_WARN_20 variable
is now removed.

Also removed here are the legacy "in place mutators" for Select
statements, and some keyword-only argument signatures in Core
have been added.

Also in the big change department, the ORM mapper() function
is removed entirely; the Mapper class is otherwise unchanged,
just the public-facing API function.  Mappers are now always
given a registry in which to participate, however the
argument signature of Mapper is not changed. ideally "registry"
would be the first positional argument.

Fixes: #7257

Change-Id: Ic70c57b9f1cf7eb996338af5183b11bdeb3e1623
2022-01-05 19:28:49 -05:00

149 lines
4.4 KiB
Python

import sqlalchemy
from sqlalchemy import Column
from sqlalchemy import Enum
from sqlalchemy import ForeignKey
from sqlalchemy import Integer
from sqlalchemy import MetaData
from sqlalchemy import select
from sqlalchemy import String
from sqlalchemy import Table
from sqlalchemy import testing
from sqlalchemy.orm import join as ormjoin
from sqlalchemy.orm import relationship
from sqlalchemy.testing import eq_
from sqlalchemy.testing import fixtures
from sqlalchemy.testing import profiling
from sqlalchemy.util import classproperty
class EnumTest(fixtures.TestBase):
__requires__ = ("cpython", "python_profiling_backend")
def setup_test(self):
class SomeEnum:
# Implements PEP 435 in the minimal fashion needed by SQLAlchemy
_members = {}
@classproperty
def __members__(cls):
"""simulate a very expensive ``__members__`` getter"""
for i in range(10):
x = {}
x.update({k: v for k, v in cls._members.items()}.copy())
return x.copy()
def __init__(self, name, value):
self.name = name
self.value = value
self._members[name] = self
setattr(self.__class__, name, self)
for i in range(400):
SomeEnum("some%d" % i, i)
self.SomeEnum = SomeEnum
@profiling.function_call_count()
def test_create_enum_from_pep_435_w_expensive_members(self):
Enum(self.SomeEnum, omit_aliases=False)
class CacheKeyTest(fixtures.TestBase):
__requires__ = ("cpython", "python_profiling_backend")
@testing.fixture(scope="class")
def mapping_fixture(self):
# note in order to work nicely with "fixture" we are emerging
# a whole new model of setup/teardown, since pytest "fixture"
# sort of purposely works badly with setup/teardown
registry = sqlalchemy.orm.registry()
metadata = MetaData()
parent = Table(
"parent",
metadata,
Column("id", Integer, primary_key=True),
Column("data", String(20)),
)
child = Table(
"child",
metadata,
Column("id", Integer, primary_key=True),
Column("data", String(20)),
Column(
"parent_id", Integer, ForeignKey("parent.id"), nullable=False
),
)
class Parent(testing.entities.BasicEntity):
pass
class Child(testing.entities.BasicEntity):
pass
registry.map_imperatively(
Parent,
parent,
properties={"children": relationship(Child, backref="parent")},
)
registry.map_imperatively(Child, child)
registry.configure()
yield Parent, Child
registry.dispose()
@testing.fixture(scope="function")
def stmt_fixture_one(self, mapping_fixture):
Parent, Child = mapping_fixture
return [
(
select(Parent.id, Child.id)
.select_from(ormjoin(Parent, Child, Parent.children))
.where(Child.id == 5)
)
for i in range(100)
]
@profiling.function_call_count(variance=0.15, warmup=2)
def test_statement_key_is_cached(self, stmt_fixture_one):
current_key = None
for stmt in stmt_fixture_one:
key = stmt._generate_cache_key()
assert key is not None
if current_key:
eq_(key, current_key)
else:
current_key = key
def test_statement_key_is_not_cached(
self, stmt_fixture_one, mapping_fixture
):
Parent, Child = mapping_fixture
# run a totally different statement so that everything cache
# related not specific to the statement is warmed up
some_other_statement = (
select(Parent.id, Child.id)
.join_from(Parent, Child, Parent.children)
.where(Parent.id == 5)
)
some_other_statement._generate_cache_key()
@profiling.function_call_count(variance=0.15, warmup=0)
def go():
current_key = None
for stmt in stmt_fixture_one:
key = stmt._generate_cache_key()
assert key is not None
if current_key:
eq_(key, current_key)
else:
current_key = key
go()