Thread: [Modeling-cvs] ProjectModeling/Modeling/doc/UserGuide FAQ.tex,1.2,1.3
Status: Abandoned
Brought to you by:
sbigaret
|
From: <sbi...@us...> - 2003-07-29 21:43:42
|
Update of /cvsroot/modeling/ProjectModeling/Modeling/doc/UserGuide
In directory sc8-pr-cvs1:/tmp/cvs-serv6376/doc/UserGuide
Modified Files:
FAQ.tex
Log Message:
Splitted the FAQ entry for accessing PK/FK values in objects
Index: FAQ.tex
===================================================================
RCS file: /cvsroot/modeling/ProjectModeling/Modeling/doc/UserGuide/FAQ.tex,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** FAQ.tex 4 Jul 2003 17:02:45 -0000 1.2
--- FAQ.tex 29 Jul 2003 18:44:17 -0000 1.3
***************
*** 25,29 ****
! \item[What if I want to see the primary key/foreign key values in my objects?]
\begin{description}
--- 25,29 ----
! \item[What if I want to see the primary key values in my objects?]
\begin{description}
***************
*** 44,53 ****
\end{itemize}
\item[Accessing it at run-time]
! However, there's a cleaner alternative to this: the primary key value can
! always be retrieved from your objects, without requiring it to be a class
! property. You can access it with \method{globalID}; every single object
! managed by the framework is uniquely identified by its global id. Among other
! things, this one has a dictionary holding the PK values:
\begin{verbatim}
--- 44,62 ----
\end{itemize}
+ \item[Using \method{CustomObject.snapshot_raw()}]
+
+ This method is the best way to get the values that will be stored for an
+ object at a given state in the database when changes are saved. It returns a
+ dictionary from which the value of the primary key can be retrieved. Be sure
+ to carefully read its documentation before using it.
+
+ This method does not require that the primary key is made a class property.
+
\item[Accessing it at run-time]
! There's a third alternative: the primary key value can always be retrieved
! from your objects, without requiring it to be a class property and apart from
! \method{snapshot_raw()}. You can access it with \method{globalID}; every
! single object managed by the framework is uniquely identified by its global
! id. Among other things, this one has a dictionary holding the PK values:
\begin{verbatim}
***************
*** 62,66 ****
def pk(self):
"Returns the pk's value"
! return self.globalID() and object.globalID()['id'] or None
\end{verbatim}
--- 71,82 ----
def pk(self):
"Returns the pk's value"
! gid=self.globalID()
! if not gid:
! return None
! if gid.isTemporary():
! # temporary gid: object has been inserted but not saved yet.
! # Change this to return any value you find more appropriate
! return gid
! return gid.keyValues()['id']
\end{verbatim}
***************
*** 68,71 ****
--- 84,153 ----
has just been inserted into an \class{EditingContext} but has not been saved
yet.
+ \end{description}
+
+ \item[What if I want to see the foreign key values in my objects?]
+
+ As a general rule, foreign keys should not be made class properties; this is
+ an even stricter rule than the one for primary keys, because the framework
+ {\em does not update foreign keys values} in objects that define them as class
+ properties (but of course, they will saved as expected in the database).
+
+ The reason is that a foreign key is usually used to store the piece of
+ information needed to store in the database a to-one relationship at the
+ object level. Say you have an entity, \code{Writer} related with the entity
+ \code{Book} in a one-to-many relationship; the table for entity \code{Book}
+ stores the primary key value for the corresponding \code{Writer} in a foreign
+ key \code{FK_Writer_id}. Suppose now that a book is moved from one author to
+ another: at the object-level, the book is removed to one author's set of books
+ and added to the others, while the book itself gets a new author:
+ \begin{verbatim}
+ >>> writer1.removeFromBooks(book)
+ >>> book.setAuthor(writer2)
+ >>> writer2.addToBooks(book)
+ \end{verbatim}
+
+ If the foreign key \code{Book.FK_Writer_id} is a class property, it is now out
+ of sync with the book's author, because it stores the former author's id while
+ it has been assigned to an other one.
+
+ However, there are several alternate solutions for accessing a foreign key
+ value, if you really insist on doing this:
+ \begin{description}
+ \item[Using CustomObject.snapshot_raw()]
+ This particular method was especially design for that purpose, as it returns
+ the raw data that do/will represent the corresponding database row. As far
+ as foreign keys are concerned, it tries everything possible to return a
+ foreign key value reflecting the current state of the graph of object. There
+ are, however, situations where the returned value can get out-of-sync;
+ please refer to the documentation of \code{CustomObject.snapshot_raw()} for
+ details.
+
+ \item[Explicitely extracting the related objects's primary key]
+
+ You can also do it manually, by traversing the relationship to get its primary
+ key, for example by adding such a method to your \code{Book}:
+ \begin{verbatim}
+ def getFKWriterId(self):
+ if self.getWriter() is None:
+ return None
+ else:
+ w_gid=self.getWriter().globalID()
+ if w_gid.isTemporary():
+ # temporary gid: object has been inserted but not saved yet.
+ # Change this to return any value you find more appropriate
+ return w_gid
+ else:
+ return w_gid.keyValues()
+ \end{verbatim}
+ This code is, in fact, the relevant part of the code of
+ \method{CustomObject.snapshot_raw()}. It's exposed here so that you can
+ see the different cases that can happen. Of course, it assumes that a to-one
+ relationship for this foreign key is defined in the object's entity --if the
+ FK is only involved in an other entity's to-many relationship with no inverse,
+ there's little to do, except relying on
+ \method{CustomObject.snapshot_raw()} (see above) that can also retrieve the
+ correct FK value after the first fetch, and after the EditingContext saved its
+ changes. Please refer to its documentation for full details.
+
\end{description}
|