On Thu, Jan 21, 2010 at 8:21 PM, Yuri Baburov <burc...@gmail.com> wrote:
> Hi Russell,
>
> Thanks, I'm rather happy too.
> It's exactly what we wanted!
>
> DB Routing API is even better than some fixed db routing format.
> I just thought about any model with GFK, like TagField from django-tagging --
> with multidb, to be effectively reusable, it has to know in what DB
> to save and load, depending on its client ContentType.
>
> Since it's solution for the problems discussed in
> http://groups.google.com/group/django-developers/browse_frm/thread/7904c7da7cb0085f/d063d2086299635e,
> could you please think about one more thing discussed there: syncdb
> targeting to correct databases.

I completely acknowledge how such a setting could be useful for any
sort of metaprogramming situation - i.e., in the case of an automated
admin interface only showing the models that are known to be
available, or in the case of syncdb.

My hesitation in implementing something to address this problem is
driven by pragmatism.

Firstly, I haven't seen an proposal that includes an elegant way to
express this database allocation information. All the formats that
I've seen amount to reproducing either INSTALLED_APPS, or worse,
having an analog of INSTALLED_APPS down to the level of individual
models. I have no desire to introduce a requirement for an
exceptionally complex data structure, especially for the single
database case.

Secondly, while I can see how this information could be useful, it
doesn't change the fact that the information is just as easy to manage
manually. Syncdb doesn't do anything special -- it just invokes sqlall
and loaddata initial_data on your database. The admin can be
completely configured to include (or not include) any object you want.
I know this isn't ideal, but it does *work*.

> Something like a db_router.get_all_databases_for_model(model) call.
> It was suggested in the thread.

Making this a programatic operation is an interesting idea, as I said
when it was proposed. Putting this callable operation in the router
avoids my previous hesitation, as it means we don't need to put
callable code in the settings file. I have some questions regarding
implementation, though:

How do you see this interacting with the stack of routers? i.e., is it
additive over all items in the stack?

How do you handle the case of removing objects from a database? For
example, if I want all models in contrib.auth to be on the 'users'
database, I can encode that rule in my AuthRouter, However if the
bucket case assigns all models to the default database, that undoes
the good work that the AuthRouter has done. How do you encode the
information of "yes, I've considered the default database as a
candidate for auth.User, and I've rejected it"?

> Another issue is bothering me:
> db_router.allow_relation doesn't convert in my head into any algorithm
> of its usage.
> Docs in this thread didn't help me either when it's called and what for.
> So I took a look into implementation, it looks like it only works as a
> validator:
> ...if not router.allow_relation(obj, self.instance): raise ValueError(...)
> But how one would suggest in which db to save object depending on the
> related object?

You are correct - allow_relation() is purely a validation hook, not a
database allocator. It is used to determine if mybook.author = john is
a valid operation - in this example, allow_relation(mybook, john)
would be invoked.

On a single database situation, both objects are on the default
database, so the relation is allowed. If you have mybook on database
d1 and john on database d2, then the relation will be prevented,
unless you define a router that allows that specific cross-database
pair - for example a master/slave router would allow the relation if
d1 and d2 are part of the same slave pool.

> I.e., let's talk about this example with GFK.

There's nothing specific about generic foreign keys here - a GFK is a
relation between two objects, and they either need to be on the same
database, or on two databases that a router agrees are compatible.
allow_relation() is what does that check.

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


Reply via email to