A. Thanks for this great idea. From your suggestion, I realize that if
I am going to use the new method, than I must enforce my __new__ (and
__init__)
to get all the unique fields as arguments. Then, if the object already
exists in the db to return it, and otherwise save the new object.

An important part of it is "save the new object", because if I won't
save the object, and one would do something like:

obj1 = MyObject(num1 = x, num2 = y)
obj1.save()
obj2 = MyObject(num1 = x, num2 = x)
obj2.num2 = y
obj2.save()

Then obj2 would not really be merged with obj1, and I will get a
constraint exception - the thing my customers afraid of the most.

So far, so good.

But my customers are really weird, and two weeks ago they asked me to
totally change the design of my project, so they will be able to use
my mapped objects, without saving them to the db. Meaning, they wants
to be able to do the following thing:
1. Create many "MyObject" instances.
2. Do some operations on them. (The features that my program supply)
3. Save some of them to the db, if they are interesting, but most of
them, just throw away, without even saving them in the first place.
The reason they asked it, is because in some of the cases, they will
want to only use the classes in the API that I provide, for stuff that
aren't "important" enough to be saved in the db, and without suffering
from the overhead of saving objects to the db.

So the case that I mentioned above with changing the attribute num2
can happen.

Another option, is not to allow them to change num2, unless the object
is saved already in the db. (using property) It would be weird.

B. So I can settle with a merge() method that returns an object. I
think it's the only solution (beside forcing them to work with saving
to the db). Actually, it's not too bad. But it's also not easy, I tell
you, to write such a function. Because what happens if one of the
things that defines me, a part of my uniqueness, is not really a
unique field, but a list of objects that are connected to me in a many-
to-many relationship from another table. And what if I need to call
merge() on each one of them. And what if two of them are evaluated to
be the same object, so I need to fix the list. oof!


On 3 דצמבר, 23:25, Michael Bayer <[EMAIL PROTECTED]> wrote:
> SQLAlchemy instruments classes using an event-based system that  
> intercepts all setattribute and collection mutation operations, and  
> logs these events as things to be reconciled when the Session is  
> flushed.   Additionally, the __dict__ of the object itself is  
> referenced by the InstanceState object which is SQLAlchemy's per-
> object manager.   Thirdly, the InstanceState object itself is placed  
> inside of the __dict__ of every object instance, and this cannot be  
> shared among multiple objects.   So for these three reasons and  
> probably more, using the old Python trick of replacing __dict__ will  
> lead to poor results.
>
> To populate the state of an object with that of another, use a  
> setattr() based approach:
>
> for k in dir(object1):
>         setattr(object2, k, getattr(object1, k))
>
> On Dec 3, 2008, at 3:47 PM, [EMAIL PROTECTED] wrote:
>
> > The reason I'm doing so, is to solve the following problem: I have an
> > object that is compounded from the fields - obj_id, num1, num2, num3.
> > obj_id is my primary key. I want to create a save method for the
> > object's class, that will do the following:
> > If the object is in the session, save it.
> > Else, if there is another object in the db with the same num1 and
> > num2, use the object in the db instead of the current one, and warn
> > the user if num3 is different.
> > So it's quite like merge, but not necessarily on the primary key. Now,
> > I want that "use the object in the db" wouldn't be by "returning" the
> > object after the merge (original object if didn't exist, and db_object
> > if existed), but really "replacing" it (self.dict =
> > existing_object.dict), so one can use that object afterwards, without
> > being confused.
>
> the most straightforward way to accomplish this would be a custom  
> __new__ method, so that when you say:
>
>         x = MyObject(num1=x, num2=y)
>
> the __new__() would do the session work to find the old object and  
> return that instead, if present.  There is a usage recipe on the Wiki  
> that does something like this, except its 0.4 specific, and uses a  
> metaclass in combination with a homegrown cache - I wrote it years ago  
> and it can be done much more simply.   Just use __new__().
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to sqlalchemy@googlegroups.com
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to