Skip to content

Commit 897b046

Browse files
committed
Refine the set_attributes API
Renamed to set_attributes from update_attributes, because "update" implies that we're hitting the db (because of the UPDATE SQL command). Set is much better for local attribute modification. This also uses the set_attribute function when instantiating the model, so that we don't take kwargs in the constructor (this was confusing me in the docs; what were those kwargs supposed to be for? Am I supposed to supply them somehow?). I factored out a check_registration function and fixed a buggy check in Model.__init__ to use that.
1 parent 22b4de0 commit 897b046

File tree

3 files changed

+35
-17
lines changed

3 files changed

+35
-17
lines changed

postgres/__init__.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -663,14 +663,29 @@ def unregister_model(self, ModelSubclass):
663663
unregister
664664
:raises: :py:exc:`~postgres.NotRegistered`
665665
666+
"""
667+
key = self.check_registration(ModelSubclass)
668+
del self.model_registry[key]
669+
670+
671+
def check_registration(self, ModelSubclass):
672+
"""Check whether an ORM model is registered.
673+
674+
:param ModelSubclass: the :py:class:`~postgres.orm.Model` subclass to
675+
check for
676+
:returns: the :py:attr:`typname` (a string) for which this model is
677+
registered
678+
:rettype: string
679+
:raises: :py:exc:`~postgres.NotRegistered`
680+
666681
"""
667682
key = None
668683
for key, v in self.model_registry.items():
669684
if v is ModelSubclass:
670685
break
671686
if key is None:
672687
raise NotRegistered(ModelSubclass)
673-
del self.model_registry[key]
688+
return key
674689

675690

676691
# Context Managers
@@ -875,7 +890,12 @@ def make(self, values):
875890
raise NotImplementedError
876891

877892
ModelSubclass = postgres.model_registry[self.name]
878-
return ModelSubclass(**dict(zip(self.attnames, values)))
893+
894+
instance = ModelSubclass()
895+
instance._set_read_only_attributes(self.attnames)
896+
instance.set_attributes(**dict(zip(self.attnames, values)))
897+
898+
return instance
879899

880900
return DelegatingCaster
881901

postgres/orm.py

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -219,33 +219,31 @@ class Model(object):
219219
db = None # will be set to a Postgres object
220220
__read_only_attributes = [] # bootstrap
221221

222-
def __init__(self, **kw):
222+
def __init__(self):
223223
if self.db is None:
224224
raise NotBound(self)
225-
if self.db is None:
226-
raise NotRegistered(self)
225+
self.db.check_registration(self)
227226
self.__read_only_attributes = [] # overwrite class-level one
228-
for k,v in kw.items():
229-
self.__read_only_attributes.append(k)
230-
self.__dict__[k] = v
231227

232228
def __setattr__(self, name, value):
233229
if name in self.__read_only_attributes:
234230
raise ReadOnly(name)
235231
return super(Model, self).__setattr__(name, value)
236232

237-
def update_attributes(self, **kw):
238-
"""Update instance attributes, according to :py:attr:`kw`.
233+
def _set_read_only_attributes(self, attribute_names):
234+
self.__read_only_attributes = attribute_names
235+
236+
def set_attributes(self, **kw):
237+
"""Set instance attributes, according to :py:attr:`kw`.
239238
240239
:raises: :py:exc:`~postgres.orm.UnknownAttributes`
241240
242241
Call this when you update state in the database and you want to keep
243-
instance attributes in sync. Note that the only attributes we can
244-
update here are the ones that were given to us by the
245-
:py:mod:`psycopg2` composite caster machinery when we were first
246-
instantiated. These will be the fields of the composite type for which
247-
we were registered, which will be column names for table and view
248-
types.
242+
instance attributes in sync. Note that the only attributes we can set
243+
here are the ones that were given to us by the :py:mod:`psycopg2`
244+
composite caster machinery when we were first instantiated. These will
245+
be the fields of the composite type for which we were registered, which
246+
will be column names for table and view types.
249247
250248
"""
251249
unknown = []

tests.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ def update_bar(self, bar):
232232
self.db.run( "UPDATE foo SET bar=%s WHERE bar=%s"
233233
, (bar, self.bar)
234234
)
235-
self.update_attributes(bar=bar)
235+
self.set_attributes(bar=bar)
236236

237237
def setUp(self):
238238
WithData.setUp(self)

0 commit comments

Comments
 (0)