More efficient contains method for proxy dict
This commit is contained in:
@@ -4,6 +4,12 @@ Changelog
|
|||||||
Here you can see the full list of changes between each SQLAlchemy-Utils release.
|
Here you can see the full list of changes between each SQLAlchemy-Utils release.
|
||||||
|
|
||||||
|
|
||||||
|
0.12.5 (2013-06-05)
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
- ProxyDict now contains None values in cache - more efficient contains method.
|
||||||
|
|
||||||
|
|
||||||
0.12.4 (2013-06-01)
|
0.12.4 (2013-06-01)
|
||||||
^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
2
setup.py
2
setup.py
@@ -24,7 +24,7 @@ class PyTest(Command):
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='SQLAlchemy-Utils',
|
name='SQLAlchemy-Utils',
|
||||||
version='0.12.4',
|
version='0.12.5',
|
||||||
url='https://github.com/kvesteri/sqlalchemy-utils',
|
url='https://github.com/kvesteri/sqlalchemy-utils',
|
||||||
license='BSD',
|
license='BSD',
|
||||||
author='Konsta Vesterinen',
|
author='Konsta Vesterinen',
|
||||||
|
@@ -18,10 +18,9 @@ class ProxyDict(object):
|
|||||||
return [x[0] for x in self.collection.values(descriptor)]
|
return [x[0] for x in self.collection.values(descriptor)]
|
||||||
|
|
||||||
def __contains__(self, key):
|
def __contains__(self, key):
|
||||||
try:
|
if key in self.cache:
|
||||||
return key in self.cache or self.fetch(key) is not None
|
return self.cache[key] is not None
|
||||||
except KeyError:
|
return self.fetch(key) is not None
|
||||||
return False
|
|
||||||
|
|
||||||
def has_key(self, key):
|
def has_key(self, key):
|
||||||
return self.__contains__(key)
|
return self.__contains__(key)
|
||||||
@@ -29,7 +28,9 @@ class ProxyDict(object):
|
|||||||
def fetch(self, key):
|
def fetch(self, key):
|
||||||
session = sa.orm.object_session(self.parent)
|
session = sa.orm.object_session(self.parent)
|
||||||
if session and sa.orm.util.has_identity(self.parent):
|
if session and sa.orm.util.has_identity(self.parent):
|
||||||
return self.collection.filter_by(**{self.key_name: key}).first()
|
obj = self.collection.filter_by(**{self.key_name: key}).first()
|
||||||
|
self.cache[key] = obj
|
||||||
|
return obj
|
||||||
|
|
||||||
def create_new_instance(self, key):
|
def create_new_instance(self, key):
|
||||||
value = self.child_class(**{self.key_name: key})
|
value = self.child_class(**{self.key_name: key})
|
||||||
@@ -39,8 +40,9 @@ class ProxyDict(object):
|
|||||||
|
|
||||||
def __getitem__(self, key):
|
def __getitem__(self, key):
|
||||||
if key in self.cache:
|
if key in self.cache:
|
||||||
|
if self.cache[key] is not None:
|
||||||
return self.cache[key]
|
return self.cache[key]
|
||||||
|
else:
|
||||||
value = self.fetch(key)
|
value = self.fetch(key)
|
||||||
if value:
|
if value:
|
||||||
return value
|
return value
|
||||||
|
@@ -5,31 +5,37 @@ from sqlalchemy.orm import sessionmaker
|
|||||||
from sqlalchemy.ext.declarative import declarative_base
|
from sqlalchemy.ext.declarative import declarative_base
|
||||||
|
|
||||||
from sqlalchemy_utils import (
|
from sqlalchemy_utils import (
|
||||||
escape_like,
|
|
||||||
sort_query,
|
|
||||||
InstrumentedList,
|
InstrumentedList,
|
||||||
PhoneNumber,
|
|
||||||
PhoneNumberType,
|
PhoneNumberType,
|
||||||
merge
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@sa.event.listens_for(sa.engine.Engine, 'before_cursor_execute')
|
||||||
|
def count_sql_calls(conn, cursor, statement, parameters, context, executemany):
|
||||||
|
try:
|
||||||
|
conn.query_count += 1
|
||||||
|
except AttributeError:
|
||||||
|
conn.query_count = 0
|
||||||
|
|
||||||
|
|
||||||
class TestCase(object):
|
class TestCase(object):
|
||||||
def setup_method(self, method):
|
def setup_method(self, method):
|
||||||
self.engine = create_engine(
|
self.engine = create_engine(
|
||||||
'postgres://postgres@localhost/sqlalchemy_utils_test'
|
'postgres://postgres@localhost/sqlalchemy_utils_test'
|
||||||
)
|
)
|
||||||
|
self.connection = self.engine.connect()
|
||||||
self.Base = declarative_base()
|
self.Base = declarative_base()
|
||||||
|
|
||||||
self.create_models()
|
self.create_models()
|
||||||
self.Base.metadata.create_all(self.engine)
|
self.Base.metadata.create_all(self.connection)
|
||||||
|
|
||||||
Session = sessionmaker(bind=self.engine)
|
Session = sessionmaker(bind=self.connection)
|
||||||
self.session = Session()
|
self.session = Session()
|
||||||
|
|
||||||
def teardown_method(self, method):
|
def teardown_method(self, method):
|
||||||
self.session.close_all()
|
self.session.close_all()
|
||||||
self.Base.metadata.drop_all(self.engine)
|
self.Base.metadata.drop_all(self.connection)
|
||||||
|
self.connection.close()
|
||||||
self.engine.dispose()
|
self.engine.dispose()
|
||||||
|
|
||||||
def create_models(self):
|
def create_models(self):
|
||||||
|
@@ -79,6 +79,25 @@ class TestProxyDict(TestCase):
|
|||||||
)
|
)
|
||||||
article.translations['en']
|
article.translations['en']
|
||||||
|
|
||||||
|
def test_contains_efficiency(self):
|
||||||
|
article = self.Article()
|
||||||
|
self.session.add(article)
|
||||||
|
self.session.commit()
|
||||||
|
article.id
|
||||||
|
query_count = self.connection.query_count
|
||||||
|
'en' in article.translations
|
||||||
|
'en' in article.translations
|
||||||
|
'en' in article.translations
|
||||||
|
assert self.connection.query_count == query_count + 1
|
||||||
|
|
||||||
|
def test_getitem_with_none_value_in_cache(self):
|
||||||
|
article = self.Article()
|
||||||
|
self.session.add(article)
|
||||||
|
self.session.commit()
|
||||||
|
article.id
|
||||||
|
'en' in article.translations
|
||||||
|
assert article.translations['en']
|
||||||
|
|
||||||
def test_contains(self):
|
def test_contains(self):
|
||||||
article = self.Article()
|
article = self.Article()
|
||||||
assert 'en' not in article.translations
|
assert 'en' not in article.translations
|
||||||
|
Reference in New Issue
Block a user