문제

syncdb가 오류를 발생시키는 코드가 있습니다(테이블이 생성되기 전에 모델에 액세스하려고 하기 때문입니다).

syncdb에서 코드가 실행되지 않도록 하는 방법이 있나요?다음과 같은 것:

if not syncdb:
    run_some_code()

감사해요 :)

편집하다:추신 - post_init 신호를 사용할 생각을 했습니다...DB에 액세스하는 코드에 대해서는 좋은 생각입니까?

더 많은 정보

요청하신 추가 정보는 다음과 같습니다 :)

예를 들어 나는 이런 일을 몇 번 겪었습니다.나는 django-cron을 해킹하고 있었고 django를 로드할 때 기존 작업이 없는지 확인해야 한다고 결정했습니다(왜냐하면 django는 설치된 모든 앱에서 작업을 검색하고 어쨌든 로드할 때 추가하기 때문입니다).

그래서 상단에 다음 코드를 추가했습니다. __init__.py 파일:

import sqlite3

try:
        # Delete all the old jobs from the database so they don't interfere with this instance of django
        oldJobs = models.Job.objects.all()
        for oldJob in oldJobs:
                oldJob.delete()
except sqlite3.OperationalError:
        # When you do syncdb for the first time, the table isn't 
        # there yet and throws a nasty error... until now
        pass

명백한 이유로 이것은 쓰레기입니다.그것은 sqlite에 묶여 있고 이 코드를 넣을 더 좋은 장소가 있지만(이것이 문제가 발생했을 때 발생한 방식입니다) 작동합니다.

보시다시피 발생하는 오류는 Operational Error(sqlite의 경우)이고 스택 추적에는 "table django_cron_job을 찾을 수 없습니다"라는 내용이 표시됩니다.

해결책

결국 목표는 다음과 같았습니다. 페이지가 로드되기 전에 일부 코드를 실행하세요..

이는 페이지를 제공하기 전에 가져와야 하기 때문에 urls.py 파일에서 실행하여 수행할 수 있습니다(분명히).

그리고 그 추악한 try/제외 블록을 제거할 수 있었습니다 :) 하느님 감사합니다(그리고 S.로트)

도움이 되었습니까?

해결책

"편집하다:추신 - post_init 신호를 사용할 생각을 했습니다...DB에 액세스하는 코드에 대해서는 좋은 생각인가요?"

절대.

테이블이 생성되기 전에 모델에 액세스하는 코드가 있는 경우 매우 큰 문제가 발생합니다.당신은 아마도 뭔가 심각하게 잘못된 일을 하고 있는 것 같습니다.

일반적으로 syncdb를 대략 한 번 실행합니다.데이터베이스가 생성됩니다.그리고 웹 애플리케이션은 데이터베이스를 사용합니다.

때로는 디자인을 변경하고 데이터베이스를 삭제하고 다시 만드는 경우도 있습니다.그리고 웹 애플리케이션은 해당 데이터베이스를 오랫동안 사용합니다.

(일반적으로) 코드가 필요하지 않습니다. __init__.py 기준 치수.실제 작업을 수행하는 실행 가능한 코드는 (거의) 없어야 합니다. __init__.py 기준 치수.이는 매우 드물며 Django에는 부적절합니다.

왜 장난을 치는 건지 모르겠어 __init__.py 언제 장고 크론 일정 조정은 에서 한다고 하더군요 urls.py.


편집하다

기록을 지우는 것은 한 가지입니다.

장난을 치다 __init__.py 그리고 Django-cron의 base.py 분명히 완전히 잘못된 방법입니다.그렇게 복잡하다면 잘못하고 있는 것입니다.

무엇을 하려는지 말하기는 불가능하지만 사소한 것이어야 합니다.

당신의 urls.py syncdb 이후와 모든 ORM 자료가 올바르게 구성되고 바인딩된 후에만 실행할 수 있습니다.

당신의 urls.py 예를 들어 일부 행을 삭제한 다음 테이블에 일부 행을 추가할 수 있습니다.이 시점에서 모든 syncdb 문제는 해결되었습니다.

왜 논리가 없나요? urls.py?

다른 팁

모델이 생성되기 전에 모델에 액세스하려는 코드는 모듈 레벨에만 존재할 수 있습니다. 예에서 알 수 있듯이 모듈이 가져 오면 실행 가능한 코드를 실행해야합니다. 이것은 당신이 추측 한 바와 같이, syncdb의 이유가 실패합니다. 모듈을 가져 오려고하지만 모듈을 가져 오는 행위로 인해 응용 프로그램 수준 코드가 실행됩니다. 당신이 원한다면 "부작용".

부작용을 유발하는 모듈 가져 오기를 피하려는 욕구는 파이썬에서 너무 강하기 때문에 if __name__ == '__main__': 실행 파이썬 스크립트를위한 컨벤션이 일반화되었습니다. 코드 라이브러리를로드하면 응용 프로그램이 실행되기 시작하면 두통이 발생합니다.

Django 앱의 경우 이것은 두통이됩니다. 의 효과를 고려하십시오 oldJob.delete() 모듈이 가져올 때마다 실행됩니다. Django Development Server에서 실행할 때 한 번만 실행되는 것처럼 보이지만 생산 환경에서는 자주 실행됩니다. 예를 들어 Apache를 사용하는 경우 Apache는 요청을 처리하기 위해 대기하는 여러 아동 프로세스를 자주 시작합니다. 오랫동안 실행되는 서버가 진행됨에 따라 Django 앱은 웹 서버를 위해 핸들러가 포크 될 때마다 부트 스트랩이 발생합니다. delete() 종종 예측할 수 없을 정도로 여러 번 부를 것입니다. 불행히도 Apache 프로세스가 초기화 될 때마다 신호를 발사 할 수 있으므로 신호는 도움이되지 않습니다.

BTW는 코드가 실수로 실행될 수있는 웹 서버 일뿐입니다. 예를 들어 EpyDoc과 같은 도구를 사용하는 경우 코드를 가져와 API 문서를 생성합니다. 이로 인해 응용 프로그램 논리가 실행되기 시작할 수 있습니다. 이는 문서 파서를 실행하는 원하지 않는 부작용입니다.

이러한 이유로, 이와 같은 청소 코드는 Cron 작업이 가장 잘 처리하는 것이 가장 좋습니다.이 작업은 주기적으로 오래된 작업을 찾고 DB를 정리합니다. 이 사용자 정의 스크립트는 수동 또는 모든 프로세스 (예 : 배포 중 또는 장치 테스트의 일부로 실행할 수도 있습니다. setUp() 깨끗한 테스트 실행을 보장하기 위해 기능). 당신이 어떻게 그렇게하든 중요한 점은 이와 같은 코드를 항상 실행해야한다는 것입니다. 명시 적으로,보다는 암시 적으로 소스 파일을 여는 결과.

도움이되기를 바랍니다. SyncDB가 실행 중인지 확인하는 방법을 제공하지는 않지만 프로덕션 배포를 염두에두고 Django 앱을 설계하면 SyncDB 문제가 마술처럼 사라집니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top