Re: Connecting to external databases from Views.py

789 views
Skip to first unread message

Russell Keith-Magee

unread,
Oct 24, 2012, 8:48:25 PM10/24/12
to django...@googlegroups.com
Hi Gregg,

Is there any reason you can't treat this as a mutliple-database configuration?


Django allows you to specify more than one database, and then direct queries at specific databases. So, you have your "main" django database for your own application, but you set up a connection to your "other" database to access the pricing report.

You'll need to write some Django model wrappers for the data in the 'other' database -- inspectdb can help with that -- but once you've done that, you'll be able to query the 'other' database as if it were a set of normal Django models.

Yours,
Russ Magee %-)

On Thu, Oct 25, 2012 at 4:43 AM, Gregg Branquinho <gr...@freightman.com> wrote:
Hi guys I am new to django and have built my first application that is being used to track and compare pricelists from vendors and it is working awesomly, I have had a request for a new feature and I am alittle boggled at to how I am going to do it..

Basically I wasnt to create a view which returns read only data(a report) from an external database which is not the django database. I dont want to copy the data to the django database and use a models as then concurreny become an issue

What would you guys recommened..

I was thinking on implenting a odbc connection from the views.py method called for my url ? but database call from the view , sound a abit dodgy.

Any ideas ?





Email Disclaimer | Quote Disclaimer | All business is undertaken subject to our General Trading Conditions, a copy of which is available on request and on our website www.freightman.com

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/ewQAAfxJlJ4J.
To post to this group, send email to django...@googlegroups.com.
To unsubscribe from this group, send email to django-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

Gregg Branquinho

unread,
Oct 25, 2012, 12:43:01 AM10/25/12
to django...@googlegroups.com
Hi Russel,

First off thank you for the suggestion, I am going to give it a whirl and see how it works out.. I have a couple of concerns about the pricing database it the
* it is on  mssql and the data is spread accross 3 database on the same server so the query would have to be cross database.. which also pose's a problem.
* the db's have like 300 table each..

Before you answer I wat thinking of accessing the database on the view *yuck* via pyodbc.

after your answer I have a couple more questions ?

Is is possible to override how a model is loaded from the database with raw sql and then overide the save and update methods to do nothing ? I have look at ovveriding __init__ but all recommendation are against it, but since I am not saving would it make any difference ?

Thanks very much for you previous answer as I feel it is pushing me towards a better solution

Kind regards
Gregg

jirka.v...@gmail.com

unread,
Oct 25, 2012, 1:32:43 AM10/25/12
to django...@googlegroups.com
Hi Gregg,

I've done something similar in the past - had several external databases (MS SQL and Oracle) attached to my Django project. These were backends of enterprise tools, hundreds of tables each.

I used the "manage.py inspectdb" command to reverse engineer each "external" DB, manually polished models I needed (inspectdb is great but can't always perfectly guess foreign key relations or field types). Then I set "managed=False" for each model of those external DB's to make sure Django won't try to modify them.

As for writing to those DB's, I had set up my DB routing so that these DB's were available only for read, not for wrining. I made sure that my code never attempted to write to those DB's. I also never used Django admin for this project.

YMMV

Jirka

P.S. You can override the save() of your models in"external DB" method to do nothing
From: Gregg Branquinho <gr...@freightman.com>
Date: Wed, 24 Oct 2012 21:43:01 -0700 (PDT)
Subject: Re: Connecting to external databases from Views.py
To view this discussion on the web visit https://groups.google.com/d/msg/django-users/-/rboXgSmzH3cJ.

Russell Keith-Magee

unread,
Oct 25, 2012, 2:58:17 AM10/25/12
to django...@googlegroups.com
On Thu, Oct 25, 2012 at 12:43 PM, Gregg Branquinho <gr...@freightman.com> wrote:
Hi Russel,

First off thank you for the suggestion, I am going to give it a whirl and see how it works out.. I have a couple of concerns about the pricing database it the
* it is on  mssql and the data is spread accross 3 database on the same server so the query would have to be cross database.. which also pose's a problem.

Genuine cross-database queries are going to be a problem regardless -- Django doesn't handle foreign keys that cross database boundaries. However, if it's just a matter of having three different data stores, that's not a problem at all -- it just means you'll have multiple entries in your database configuration.

* the db's have like 300 table each..

There's a "yikes" factor here in terms of the number of tables you'll need to configure, but inspected will help you out here, and once that's done, you shouldn't have any problems in practice.  
 
Before you answer I wat thinking of accessing the database on the view *yuck* via pyodbc.

after your answer I have a couple more questions ?

Is is possible to override how a model is loaded from the database with raw sql and then overide the save and update methods to do nothing ? I have look at ovveriding __init__ but all recommendation are against it, but since I am not saving would it make any difference ?

You can certainly override the save() method and make it a no-op; you don't need to touch __init__ at all to do this. Just make a subclass of django.db.models.Model that defines a no-op save() method, and make sure all your "views" extend this base class. Simliarly, you can override the model manager to provide a default query set that makes the update a no-op. As a third line of defence, you can write a database router that directs write queries to a no-op database, so if something does accidentally trigger a database write, it won't allow the update to occur.

Yours,
Russ Magee %-)

Gregg Branquinho

unread,
Oct 29, 2012, 3:58:52 AM10/29/12
to django...@googlegroups.com
Hi guys thanks for the help so Far, from what I understand this is what I have to do for models.. 

<code>
from django.db import models

class ModelReadOnly(models.Model):
    
    def save(self, *args, **kwargs):
        pass
        #raise NotImplemented
    
    class Meta:
        managed = False

class AppLog(ModelReadOnly):
    log_no = models.AutoField(db_column=u'LOG_NO') # Field name made lowercase.
    module_id = models.CharField(max_length=25, db_column=u'MODULE_ID') # Field name made lowercase.
    user_name = models.CharField(max_length=25, db_column=u'USER_NAME') # Field name made lowercase.
    full_name = models.CharField(max_length=80, db_column=u'FULL_NAME') # Field name made lowercase.
    description = models.CharField(max_length=3500, db_column=u'DESCRIPTION', blank=True) # Field name made lowercase.
    date_time_stamp = models.DateTimeField(db_column=u'DATE_TIME_STAMP') # Field name made lowercase.
    class Meta:
        db_table = u'APP_LOG'

</code>

Thanks should take car of the db structure and the save, now I need to look at the model manager to circumvent the update.. ?

Gregg Branquinho

unread,
Oct 29, 2012, 4:44:59 AM10/29/12
to django...@googlegroups.com
from django.db import models


class ModelManagerReadOnly(model.Manager):
    def update(self, *args, **kwargs):
        pass
          

class ModelReadOnly(models.Model):
     objects = ModelManagerReadOnly() # The ReadOnly manager.
    
    def save(self, *args, **kwargs):
        pass
        #raise NotImplemented
    
    def delete(self, *args, **kwargs):
        pass
    
    class Meta:
        managed = False
        abstract = True



class AppLog(ModelReadOnly):
    log_no = models.AutoField(db_column=u'LOG_NO') # Field name made lowercase.
    module_id = models.CharField(max_length=25, db_column=u'MODULE_ID') # Field name made lowercase.
    user_name = models.CharField(max_length=25, db_column=u'USER_NAME') # Field name made lowercase.
    full_name = models.CharField(max_length=80, db_column=u'FULL_NAME') # Field name made lowercase.
    description = models.CharField(max_length=3500, db_column=u'DESCRIPTION', blank=True) # Field name made lowercase.
    date_time_stamp = models.DateTimeField(db_column=u'DATE_TIME_STAMP') # Field name made lowercase.
    class Meta:
        db_table = u'APP_LOG'

updated code

Tom Evans

unread,
Oct 29, 2012, 5:41:01 AM10/29/12
to django...@googlegroups.com
If you derive a model from a base class, and want the base class's
Meta class to have an effect, you must derive the child class's Meta
class from the base class's Meta class:

https://docs.djangoproject.com/en/1.4/topics/db/models/#meta-inheritance

The net result is that with your current code, the 'managed' attribute
on the Meta class does not exist on the derived classes.

Cheers

Tom

Gregg Branquinho

unread,
Oct 29, 2012, 6:54:52 AM10/29/12
to django...@googlegroups.com, teva...@googlemail.com
Thanks Tom for this info I have adjusted the models .py as such..

from django.db import models

class ModelManagerReadOnly(model.Manager):
    def update(self, *args, **kwargs):
        pass
 
 class ModelReadOnly(models.Model):
     objects = ModelManagerReadOnly() # The ReadOnly manager.
    
    def save(self, *args, **kwargs):
        pass
        #raise NotImplemented
    
    def delete(self, *args, **kwargs):
        pass
    
    class Meta:
        managed = False
        abstract = True

class AppLog(ModelReadOnly):
    log_no = models.AutoField(db_column=u'LOG_NO') # Field name made lowercase.
    module_id = models.CharField(max_length=25, db_column=u'MODULE_ID') # Field name made lowercase.
    user_name = models.CharField(max_length=25, db_column=u'USER_NAME') # Field name made lowercase.
    full_name = models.CharField(max_length=80, db_column=u'FULL_NAME') # Field name made lowercase.
    description = models.CharField(max_length=3500, db_column=u'DESCRIPTION', blank=True) # Field name made lowercase.
    date_time_stamp = models.DateTimeField(db_column=u'DATE_TIME_STAMP') # Field name made lowercase.
    class Meta(ModelReadOnly.Meta):
        db_table = u'APP_LOG'
Reply all
Reply to author
Forward
0 new messages