On Fri, Jul 9, 2010 at 1:41 AM, tiemonster <m...@tiemonster.info> wrote:
> It seems that when running unit tests, the test runner not only
> creates all tables on both of my connections (which it should not do,
> if I read the documentation correctly),

Tables will be created on all connections, according to the syncdb
rules of your router (by default, all tables on all databases).
However, the non-default databases will not be flushed at the end of
each test unless you specify multi_db=True in your test case.

This is done for performance reasons; unless you're specifically
testing cross-database behavior, the overhead of setting up and
tearing down multiple databases is quite onerous.

> but also tries to create the
> cache table twice, causing the error below. Please let me know if I'm
> missing something here. I have two MySQL connections, called default
> and datastore, and have my CACHE_BACKEND set to db://cache_table.

It sounds like you may have found a problem (or, a series of related
problems). At present, the cache database backend doesn't have any
specific multi-db awareness. The CACHE_BACKEND setting doesn't allow
you to specify which database the cache backend should operate upon;
the backend itself just gets a cursor on the 'default' backend.

On top of that, the createcachetable management command accepts a
--database argument when it is run from the command line, which allows
you to control where the cache table is created... but the
create_test_db() utility doesn't pass that option when it
programatically invokes createcachetable as part of database setup.
So, when you try to create a test database, and you've specified a
database cache backend, it will repeatedly try to create the database
cache table on the default database.

This explains why TEST_MIRROR fixed your problem. When you set
TEST_MIRROR, you're effectively telling the test infrastructure that
you don't need to create a specific database, so you avoid
accidentally trying to create the cache table twice.

So - yes, this should be logged as a ticket.

As for a fix, there are three parts that are required.

Firstly, create_test_db() should pass the database flag to the
createcachetable command when it is invoked.

Secondly, the cache backend itself needs to be made multi-db aware, so
it doesn't just use the default database connection.

Thirdly, the create_test_db() call needs an additional check -- as
well as checking if the database cache backend is in use, it needs to
check if the test database that is being created actually requires the
cache table.

Conceptually, problems 2 and 3 need to be fixed by the router.
However, the API for the router requires that you provide a model as
the basis for decision making; since the database cache backend
doesn't use a Django model this won't really work well in practice.

A better approach is probably to just add extra arguments to the
CACHE_BACKEND setting when db:// is specified -- so, something like:

CACHE_BACKEND="db://mycachetable?max_entries=100&write_db=foo&read_db=slave1&read_db=slave2"

which would mean that:
 * the table would only be created on the database alias "foo"
 * one of [slave1, slave2] would be selected at random for read purposes.

When unspecified, read_db would default to the same value as write_db;
if write_db is unspecified, it would default to 'default'.

Yours,
Russ Magee %-)

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-us...@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to