[Choose Database based on geolocalization]

66 views
Skip to first unread message

xina towner

unread,
Mar 7, 2015, 3:09:28 PM3/7/15
to django...@googlegroups.com
Hi,

is there any possibility that we could select the database to which route a request of a user depending on the geolocalization of the client? Or the user country?

I've check some documentation of the dbrouters, but I am concerned that if a user travels to another country he is going to be routed to the wrong database.

Does anybody have know how to solve this issue?


--
Gràcies,

Rubén

Russell Keith-Magee

unread,
Mar 7, 2015, 6:42:48 PM3/7/15
to Django Users
Hi Xina,

The short answer is "not easily, and not within Django".

Django's DB Routers don't contain any detail about the request, so there's no ability to geolocated the requesting IP for routing purposes. For the record, this is because Django is a general purpose toolkit - there's no guarantee that a request to access the DB has come as a result of a HTTP request - it might come from a standalone script, which won't have an IP address.

So - you'll need to look further up the stack to do this sort of routing. My suggestion would be to look at the web server level. 

The simplest approach would be to deploy multiple "versions" of your app on different subdomains - "asia.example.com, us.example.com, europe.example.com", and rely on users to pick the right domain. Each version would be running exactly the same code - but they would each have a different settings file, pointing to the asia database, us database and so on.

A more complex approach would be to use IP-based routing at the web server. NginX has plugins like GeoIP to redirect traffic based on the IP of the requesting user. In this configuration, you'd still have multiple servers, but the NginX server would be directing traffing from the root "example.com" to the right geolocated server.

Yours,
Russ Magee %-)




--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CANGESS-w7ctv9AeGkbBymuhLgYAdEZqcDSrkwPCd3Rw8-6Rkjw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Petros Moisiadis

unread,
Mar 8, 2015, 9:18:07 AM3/8/15
to django...@googlegroups.com
On 03/08/2015 01:42 AM, Russell Keith-Magee wrote:
> Hi Xina,
>
> The short answer is "not easily, and not within Django".
>
> Django's DB Routers don't contain any detail about the request, so
> there's no ability to geolocated the requesting IP for routing
> purposes. For the record, this is because Django is a general purpose
> toolkit - there's no guarantee that a request to access the DB has
> come as a result of a HTTP request - it might come from a standalone
> script, which won't have an IP address.
>

Django's DB routers have the notion of 'hints'. So, theoretically, a
hint with the HTTP request object could be passed to a db router (when
access to a database comes as a result of an HTTP request) or not passed
at all (if the database request is triggered by other means, e.g. a
standalone script). I am not saying that Xina's use case would be served
better with such an implementation though. Just pointing out that, in
theory, there should be no inherent restriction in Django supporting this.

sena...@gmail.com

unread,
Mar 8, 2015, 9:57:28 AM3/8/15
to django...@googlegroups.com

Yes, it should be quite straightforward to implement.

Setup the appropriate databases, say, db_asia, db_euro, etc. Create separate apps asia, euro, etc. Create a db_router that makes asia models sticky to db_asia, etc.

Create a handler that returns the appropriate model to use based on geolocation. If you don’t want to create region specific apps, you can make your handler return the appropriate db to use based on geolocation info. Django makes it easy to specify the database to fetch information from.

If you want users to remain sticky to specific db when travelling, one way to do this will be to assign a db to users when they create accounts. You can save db and user authentication info when they log in and fetch from the appropriate database as before.

Russell Keith-Magee

unread,
Mar 8, 2015, 8:01:38 PM3/8/15
to Django Users
Yes, DB Routers support hints. How are you planning to inject those hints into the router? Router arguments aren't exposed to the end user when you do a query - they're automatically generated by the query, and only include details about related objects in the query.

Yours,
Russ Magee %-) 

Petros Moisiadis

unread,
Mar 9, 2015, 4:23:35 AM3/9/15
to django...@googlegroups.com
On 03/09/2015 01:58 AM, Russell Keith-Magee wrote:
> Yes, DB Routers support hints. How are you planning to inject those
> hints into the router? Router arguments aren't exposed to the end user
> when you do a query - they're automatically generated by the query,
> and only include details about related objects in the query.

A quick and draft thought would be to have a middleware that manipulates
the ConnectionRouter class, which is instantiated when making database
queries. But, before looking at the implementation details, maybe we
should first think if it would be useful in general as a feature to pass
a hint for the HTTP request to the DB routers.

James Schneider

unread,
Mar 9, 2015, 6:38:25 AM3/9/15
to django...@googlegroups.com

To me, the question needs more explanation. If a request is made of a server in the US, how does it make any sense to send a database query from that server in the US over to Luxembourg if that is in the proximity of where the user is located? Efficiency? No, that would actually cause double the traffic over close to the same distance. Different data? I would hope not, otherwise you should definitely just store the connection of a user to a database to be used.

In reality, the current location of the user should somewhat irrelevant, and known profile information (such as the user has previously accessed the US site even though they are currently in Madrid) about that user should redirect them to the appropriate servers, probably using the subdomain strategy that Russell originally suggested. First time users could potentially be geo-redirected based on IP, but most interfaces I've seen just ask what resources they need (or the country they want to use) and redirect accordingly.

-James

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.

xina towner

unread,
Mar 9, 2015, 6:47:38 AM3/9/15
to django...@googlegroups.com
It's a requirements of a client.

I'm not happy to do this...but as I couldn't find any nice solution, maybe because of my limited knowledge, I've asked the mail list.
But it seems that a nice solution does not exists so..it's going to be funny.

Thanks for the tentative solutions by the way.

James Schneider

unread,
Mar 9, 2015, 7:14:20 AM3/9/15
to django...@googlegroups.com

Perhaps you can investigate more into the 'why' portion of the requirement (which is what I was interested in)? You may be able to convince them to abandon/modify their requirement if you lay out the technical issues and complication they are introducing, and for what gain?

I suspect the feature you are looking for doesn't have great support because a) there are (usually) better alternatives at other levels of the application stack (ie Russell's solution), or b) user data for an application is most often shared within a single database or c) redundancy or load sharing of the databases will likely be on the DB side rather than be controlled by the app itself. The app shouldn't care whether it is talking to a single database or a cluster of 100.

What you're trying to do isn't impossible, I was just trying to make sure the effort justifies the reward, although giving the customer what they want even though it is...suboptimal...and getting paid may be the "best" way to go, even though I'm cringing as I write that.

-James

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.

xina towner

unread,
Mar 9, 2015, 4:42:35 PM3/9/15
to django...@googlegroups.com
I'm in process of thinking whether its worth or not...

Russell's solution was one of the first solutions that I thought of but it has it's flaws, although obviously is one of the options that it's on the table as it's not as painful as another solution would be.

I could try to convince them although I already know for a fact that in some cases some local laws are involved...in that case I have no other option than ...

Reply all
Reply to author
Forward
0 new messages