Specifying DB table names for intermediate table in an M2M relation?

378 views
Skip to first unread message

Geta

unread,
Jul 19, 2006, 6:56:50 PM7/19/06
to Django users
What's the easiest way to have Django use an existing table for the
intermediate table for a ManyToManyField? I have a legacy database,
with two tables and an intermediate table for the M2M relationship
between them -- all these are pretty similar to what Django would
create, but the table and column names are different. I know you can
specify META.db_table to specify database table names and db_column for
field names, but I couldn't see where/if this could be set for a
ManyToManyField -- is it possible?

Thanks,
Geta

Russell Keith-Magee

unread,
Jul 19, 2006, 8:19:25 PM7/19/06
to django...@googlegroups.com
On 7/20/06, Geta <geetanjali...@gmail.com> wrote:

I know you can
specify META.db_table to specify database table names and db_column for
field names, but I couldn't see where/if this could be set for a
ManyToManyField -- is it possible?

There isn't a simple way to do this - however, if you're feeling adventurous, there are a few things that might be worth trying.

The m2m table name is determined by the m2m_db_table() method on the ManyToManyField itself (from django.db.models.fields.related.py). Similarly, the m2m_column_name() and m2m_reverse_name() methods on the ManyToManyField determine the column names that are used on the m2m table. These three functions are curried versions of more generic functions (_get_m2m_db_table, et al). At present, they are hard coded to use the field and related model names as the basis for naming of the m2m table.

If you were to subclass ManyToManyField and override the _get_m2m versions of the functions, or modify the m2m_...() functions on a field instance, you might find that you can point the m2m relation at your existing table.

As a more general solution - your idea is reasonable enough, and shouldn't be too hard to implement. I would suggest submitting it as an enhancement request.

Yours,
Russ Magee %-)

Malcolm Tredinnick

unread,
Jul 19, 2006, 9:17:46 PM7/19/06
to django...@googlegroups.com

Not yet.

There's a ticket I stumbled across yesterday that asks for this, too
(#785). I think it's not an unreasonable idea, so we should add
something like that in the near- to medium-term future.

Malcolm


Marc de Graauw

unread,
Jul 20, 2006, 4:58:09 AM7/20/06
to Django users

Geta wrote:
> What's the easiest way to have Django use an existing table for the
> intermediate table for a ManyToManyField?

In PostgreSQL you could try to:
- let Django create its m2m table
- drop it
- recreate it as a view on your original m2m table
- create an rule 'AS ON INSERT ... DO INSTEAD"

A small script which shows something like this:

/* Your original m2m table */
create table t (k int, c1 int, c2 int);
/* The view, which should copy Django's m2m table */
create view v as select k as id, c1 as t1_id, c2 as t2_id from t;
/* A rule which redirects inserts to the original m2m table */
create rule r as on insert to v
do instead
insert into t values (NEW.id, NEW.t1_id, NEW.t2_id);
/* insert some values in the view */
insert into v values (1, 1, 1);
insert into v values (2, 2, 2);
insert into v values (3, 3, 3);
/* inserts have actually gone in the original m2m table */
select * from t;

You would also need rules for updates and deletes on the view.

On MS SQLServer views are updatable to a certain extent by default, so
something similar would work there.

Of course the Django-generated m2m table and the original one have to
be pretty similar for this to work.

Cheers,

Marc

Reply all
Reply to author
Forward
0 new messages