2014-07-25 19 views
8

Czy można dodać połączenie do bazy danych, więc przy korzystaniu z niego dozwolone są jedynie zapytania wybrane?Utwórz tylko do odczytu połączenie z bazą danych MySQL w Django

Coś takiego byłoby świetnie:

DATABASES = { 
    #can do update, insert, etc... 
    'default': { 
     'ENGINE': 'django.db.backends.mysql', 
     'USER': 'root', 
     'PASSWORD': '12345', 
    } 
    #select only 
    'default_readonly': { 
     'ENGINE': 'django.db.backends.mysql', 
     'NAME': 'mydb', 
     'PASSWORD': '12345', 
     'READONLY': True, 

    } 
} 

Nie mogę znaleźć nic prostego.

Odpowiedz

5

Z tego, co wiem, Django nie zapewnia żadnych opcji ograniczenia połączenia z bazą danych do trybu "tylko do odczytu". Można to jednak zrobić, tworząc użytkownika tylko do odczytu w silniku bazy danych MySQL.

Innym pomysłem, po stronie kodu Django, byłoby utworzenie własnego kursora, który zgłasza wyjątek, jeśli zostanie wywołany execute lub executemany. Możesz spojrzeć na this module django-db-readonly.

5

Powinieneś ustawić uprawnienia dla użytkownika użytego do połączenia (zamiast "root").

Powoduje to insert/update/delete zapytań podnieść błędy, które należy zarządzać w was poglądów (w razie potrzeby)

+1

Dzięki Don! Jednak wolę rozwiązanie Maxime, ponieważ utrzymuje mnie wewnątrz Django (i dlatego wewnątrz Git). – YardenST

3

Od Django 1.2 można określić klasę router do zapytania 'route' do różnych baz danych (https://docs.djangoproject.com/en/dev/topics/db/multi-db/) .

użyć jednego db do odczytu i do zapisu jeden można zdefiniować klasę Routera tak:

Class MyRouter(object): 
    def db_for_read(self, model, **hints): 
     return 'default_readonly' 

    def db_for_write(self, model, **hints): 
     return 'default' 

    def allow_syncdb(self, db, model): 
     return db == 'default' 

i umieścić to w swoim settings.py

DATABASE_ROUTERS = ['path.to.MyRouter'] 

To działa dla mnie tak długo jak nie używam select_for_update(), która jest uważana za operację odczytu, ale potrzebuje dostępu do zapisu do bazy danych. Jedyne obejście, które do tej pory znalazłem, to zastąpienie select_for_update w klasie Manager w podobny sposób:

class MyManager(Manager): 

    def select_for_update(self, *args, **kwargs): 
     return super(MyManager, self).using('default').select_for_update(*args, **kwargs) 
+0

Faktycznie zauważam, że problem select_for_update został rozwiązany w Django 1.7 przez wzięcie pod uwagę select_for_update operacji zapisu. – Oberix