Is persistence required for associations?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Is persistence required for associations?

Sam Newman

I'm trying to write a simple unit test for one of my models. I have
two models - Build and Project. A Project has multiple Builds. I want
to be able to create a build object, with an association to a Project.
However I seem unable to do this unless I actually save the Project
instance to the database - even if I have no intention of ever saving
the build. For example:

>>> project = Project()
>>> project.id = 4
>>> build = Build()
>>> build.project = project
>>> build.project
Traceback (most recent call last):
  File "<console>", line 1, in ?
  File "c:\tools\python\python2.4\lib\site-packages\Django-0.95-py2.4.egg\django
\db\models\fields\related.py", line 169, in __get__
    rel_obj = self.field.rel.to._default_manager.get(**params)
  File "c:\tools\python\python2.4\lib\site-packages\Django-0.95-py2.4.egg\django
\db\models\manager.py", line 67, in get
    return self.get_query_set().get(*args, **kwargs)
  File "c:\tools\python\python2.4\lib\site-packages\Django-0.95-py2.4.egg\django
\db\models\query.py", line 213, in get
    raise self.model.DoesNotExist, "%s matching query does not exist." % self.mo
del._meta.object_name
DoesNotExist: Project matching query does not exist.

In other persistence layers - Hibernate comes to mind - if I directly
create the association as I have done here, I can query that
association before persistence. If I have to create lots of fake data,
and always hit the database it is going to add significant bloat to my
unit testing.

Any thoughts?
--
sam
http://www.magpiebrain.com/

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to [hidden email]
To unsubscribe from this group, send email to [hidden email]
For more options, visit this group at http://groups.google.com/group/django-users
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

Re: Is persistence required for associations?

Malcolm Tredinnick

On Thu, 2006-10-12 at 13:06 +0100, Sam Newman wrote:
> I'm trying to write a simple unit test for one of my models. I have
> two models - Build and Project. A Project has multiple Builds. I want
> to be able to create a build object, with an association to a Project.
> However I seem unable to do this unless I actually save the Project
> instance to the database - even if I have no intention of ever saving
> the build. For example:

Somehow the object being referred to needs to get a primary key value so
that it can be stored in the referring object (otherwise, no association
would be possible). Normally, that happens by saving the first object.

Looks like we actually enforce that by trying to retrieve the original
from the database.

[...]
> In other persistence layers - Hibernate comes to mind - if I directly
> create the association as I have done here, I can query that
> association before persistence.

It's not a common use-case, though, since if you are referring to
another object, you are presumably going to save them. Django asks you
to save first.

I'm not sure whether this is really worth working around just for the
slight testing speed up. However, I also haven't looked at the code and
tried to work out what the implications of doing so would be. Maybe it's
a reasonable change, maybe not. The risk is that if we don't require a
save first, then either the user or Django needs to ensure the saves are
done in the right order, otherwise the database check constraint is
going to be violated (the referred-to object must be saved first).
Asking Django to serialise the saves in the right order is something I
thought we had kind of decided not to do quite a few months ago in a
similar discussion, but my memory may be failing me on this point.

> If I have to create lots of fake data,
> and always hit the database it is going to add significant bloat to my
> unit testing.

The SQLite in-memory database (a database with the name of ":memory:")
is perfect for this sort of thing. No disk access involved.

Regards,
Malcolm


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to [hidden email]
To unsubscribe from this group, send email to [hidden email]
For more options, visit this group at http://groups.google.com/group/django-users
-~----------~----~----~----~------~----~------~--~---

Reply | Threaded
Open this post in threaded view
|

Re: Is persistence required for associations?

Sam Newman

On 10/12/06, Malcolm Tredinnick <[hidden email]> wrote:

> [...]
> > In other persistence layers - Hibernate comes to mind - if I directly
> > create the association as I have done here, I can query that
> > association before persistence.
>
> It's not a common use-case, though, since if you are referring to
> another object, you are presumably going to save them. Django asks you
> to save first.

In environments where we use Hibernate, it is a common use-case - we
write a lot of unit tests (we make heavy use of TDD). Hibernate does
of course introduce a lot of complexity by having the concept of the
session.

The main concept behind TDD is that by using unit tests (tests which
test one class) to drive out the expected behaviour of your code, you
end up with highly cohesive, losely coupled code which good test
coverage.

Having to set up a test database and test data in order to create unit
tests makes writing unit tests more complicated.

> > If I have to create lots of fake data,
> > and always hit the database it is going to add significant bloat to my
> > unit testing.
>
> The SQLite in-memory database (a database with the name of ":memory:")
> is perfect for this sort of thing. No disk access involved.

I'll certainly try that - what I think I'll do is setup some test
fixtures which clean out the in-memory database before and after each
test. I will of course have to maintain two separate settings - one
for unit tests and one for development.

Anyway, if I come up with anything interesting I'll post it back.


--
sam
http://www.magpiebrain.com/

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to [hidden email]
To unsubscribe from this group, send email to [hidden email]
For more options, visit this group at http://groups.google.com/group/django-users
-~----------~----~----~----~------~----~------~--~---