2010-08-16 11 views
39

Jestem nowy dla Pythona i Django, a gdy podążam za Django Book dowiedziałem się o poleceniu "python manage.py syncdb", które wygenerowało dla mnie tabele bazy danych. W środowisku programistycznym używam sqlite w bazie danych pamięci, więc jest on automatycznie kasowany za każdym razem, gdy restartuję serwer. Więc jak mam skrypt to polecenie „syncdb”? (Powinno to być zrobione wewnątrz „” settings.py pliku?)W django, jak wywołać podkomendę "syncdb" ze skryptu inicjującego?

WYJAŚNIENIE

PO używa bazy danych w pamięci, który musi być inicjowane na początku każdego procesu pracującego z modelami Django zdefiniowanymi dla tej bazy danych. Jaki jest najlepszy sposób na zainicjowanie bazy danych (raz na początek procesu). Może to być przeprowadzanie testów lub uruchamianie serwera za pośrednictwem manage.py runserver lub za pośrednictwem procesu serwera WWW (na przykład z WSGI lub mod_python).

Odpowiedz

69

zarządzanie Wszystko Django can be accessed programmatically:

from django.core.management import call_command 
call_command('syncdb', interactive=True) 

Idealnie byłoby użyć sygnału pre-startowy na runserver aktywować, ale taki sygnał doesn't exist. Tak, rzeczywiście, tak jak bym sobie tego, gdybym można byłoby stworzyć polecenie zarządzania zwyczaj, jak runserver_newdb i wykonać to wewnątrz niego:

from django.core.management import call_command 
call_command('syncdb', interactive=True) 
call_command('runserver') 

Zobacz the documentation uzyskać więcej informacji na temat pisania poleceń zarządzania zwyczaj .

+0

W którym pliku (w typowym projekcie django) umieściłeś "z django.core.management import call_command call_command ('syncdb', interactive = True)"? –

+0

@ EdwardD'Souza: Do tego użytku przypadku, umieściłbym go w 'settings.py' lub w skrypcie zaimportowanym z' settings.py' –

5

Aktualizacja

Dodałem skrypt o nazwie run.sh w katalogu głównym projektu. To działało na mnie z bazy danych SQLite:

#!/usr/bin/python 
from django.core.management import call_command 
call_command('syncdb') 
call_command('runserver') 

Original Odpowiedź

Nie jestem pewien, czy rozumiem co masz na myśli przez „skryptów polecenia syncdb”. Zwykle wykonuj python manage.py syncdb z wiersza poleceń. Zwykle robi się to po dodaniu nowych modeli. Jeśli chcesz, możesz to łatwo zrobić za pomocą prostego skryptu powłoki. Nie widzę powodu, aby umieszczać (lub wywoływać) syncdb z poziomu settings.py.

Czy możesz dodać więcej szczegółów do swojego pytania? Dodaj kontekst i wyjaśnij, co dokładnie chcesz zrobić?

+0

Mam nadzieję, że powoływanie się na ten „syncdb'command jako dowolną inną metodę Pythona i umieść wywołanie w pliku settings.py, więc za każdym razem, gdy uruchomię aplikację, automatycznie tworzy ona bazę danych –

+0

Rozumiem. Nie jestem przekonany, że 'settings.py' jest najlepszym miejscem, aby go zachować. Możemy zgodzić się z tym nie zgodzić :) –

+0

Czy masz jakieś inne sugestie? Jestem zupełnie nowy w python. Jak stwierdził Craig Trader, wywołanie "syncdb" musi się odbywać w tym samym procesie, więc domyślam się, że skrypty powłoki nie wchodzą w grę. –

0

Można utworzyć nowy skrypt, który nazywamy zamiast manage.py że nazywa manage.py:

from subprocess import call 
call(["python", "manage.py", "syncdb"]) 
call(["python", "manage.py", "runserver"]) 

Jeśli nie trzeba dodać admina można zmienić drugą linię:

call(["python", "manage.py", "syncdb", "--noinput"]) 

Zakładam, że to, co próbujesz zrobić, to utworzyć bazę danych, a następnie uruchomić serwer za każdym razem za pomocą jednego polecenia. Polecenia

+0

Miałem nadzieję uzyskać dostęp do "syncdb" jako pewnego rodzaju API Pythona, ale to jest ok. –

+0

To prawdopodobnie nie będzie działać dla bazy danych w pamięci, ponieważ każde 'wywołanie' wywołuje osobny proces, który miałby własną bazę danych w pamięci –

+0

Tak, masz rację, to prawdopodobnie pozostawia skrypty bashowe –

9

Zgodnie z sugestią "Where to put Django startup code?" możesz użyć oprogramowania pośredniego do uruchomienia kodu. Dokumentacja Django to here.

Na przykład (untested):

startup.py:

from django.core.exceptions import MiddlewareNotUsed 
from django.conf import settings 
from django.core.management import call_command 

class StartupMiddleware(object): 
    def __init__(self): 
     # The following db settings name is django 1.2. django < 1.2 will use settings.DATABASE_NAME 
     if settings.DATABASES['default']['NAME'] == ':memory:': 
      call_command('syncdb', interactive=False) 

     raise MiddlewareNotUsed('Startup complete') 

i w settings.py:

MIDDLEWARE_CLASSES = (
    'your_project.middleware.startup.StartupMiddleware', 

    # Existing middleware classes here 
) 
+1

+1, bardzo podoba mi się to rozwiązanie, ponieważ po prostu dzieje się "automagicznie" i nie wymaga uruchamiania specjalnych skryptów. –

+0

Naprawdę fajne rozwiązanie –

Powiązane problemy