mirror of
https://github.com/sqlalchemy/sqlalchemy.git
synced 2026-05-14 12:47:22 -04:00
01c50c64e3
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
149 lines
4.4 KiB
Python
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()
|