2013-04-08 4 views
0

매일 3시에 MySQL에서 데이터를 다운로드하는 크론 작업이 있습니다.이 연결을 테스트하여 다운로드하면 작동합니다. 때때로 다운로드가 부분적으로 실패합니다. (부분 다운로드) py 스크립트를 다시 실행하면 짖어 버립니다. 키 2의 중복 항목 오류.Django - mysql IntegrityError 1062

db를 채우는 스크립트를 다시 실행할 수 있도록 스크립트를 실행하고 이전 밤의 항목 만 지울 수 있기를 원합니다. 이 테이블에는 3 개의 다른 테이블이 있습니다. django는 yesterdays 레코드를 삭제하는 SQL 스크립트를 만드는 경우 어떻게 할 것입니까? 다른 테이블에 필요한 추가 기능을 자동으로 삭제합니까, 아니면 스크립트에서도이 작업을 수행해야합니까?

Traceback (most recent call last): 
    File "manage.py", line 10, in <module> 
    execute_from_command_line(sys.argv) 
    File "/usr/local/lib/python2.6/site-packages/django/core/management/__init__.py", line 443, in execute_from_command_line 
    utility.execute() 
    File "/usr/local/lib/python2.6/site-packages/django/core/management/__init__.py", line 382, in execute 
    self.fetch_command(subcommand).run_from_argv(self.argv) 
    File "/usr/local/lib/python2.6/site-packages/django/core/management/base.py", line 196, in run_from_argv 
    self.execute(*args, **options.__dict__) 
    File "/usr/local/lib/python2.6/site-packages/django/core/management/base.py", line 232, in execute 
    output = self.handle(*args, **options) 
    File "/usr/local/django/grease/greaseboard/management/commands/import_patients.py", line 27, in handle 
    mrn = row.MRN, 
    File "/usr/local/lib/python2.6/site-packages/django/db/models/manager.py", line 134, in get_or_create 
    return self.get_query_set().get_or_create(**kwargs) 
    File "/usr/local/lib/python2.6/site-packages/django/db/models/query.py", line 449, in get_or_create 
    obj.save(force_insert=True, using=self.db) 
    File "/usr/local/lib/python2.6/site-packages/django/db/models/base.py", line 463, in save 
    self.save_base(using=using, force_insert=force_insert, force_update=force_update) 
    File "/usr/local/lib/python2.6/site-packages/django/db/models/base.py", line 551, in save_base 
    result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw) 
    File "/usr/local/lib/python2.6/site-packages/django/db/models/manager.py", line 203, in _insert 
    return insert_query(self.model, objs, fields, **kwargs) 
    File "/usr/local/lib/python2.6/site-packages/django/db/models/query.py", line 1576, in insert_query 
    return query.get_compiler(using=using).execute_sql(return_id) 
    File "/usr/local/lib/python2.6/site-packages/django/db/models/sql/compiler.py", line 910, in execute_sql 
    cursor.execute(sql, params) 
    File "/usr/local/lib/python2.6/site-packages/django/db/backends/util.py", line 40, in execute 
    return self.cursor.execute(sql, params) 
    File "/usr/local/lib/python2.6/site-packages/django/db/backends/mysql/base.py", line 114, in execute 
    return self.cursor.execute(query, args) 
    File "/usr/local/lib/python2.6/site-packages/MySQLdb/cursors.py", line 174, in execute 
    self.errorhandler(self, exc, value) 
    File "/usr/local/lib/python2.6/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler 
    raise errorclass, errorvalue 
django.db.utils.IntegrityError: (1062, "Duplicate entry '000xxxxxxxx' for key 2") 

답변

0

일이 얼마나 큰 아니 생각하지만, 비슷한 문제에 대해 나는 세이브 포인트와 함께 트랜잭션을 사용 - https://docs.djangoproject.com/en/dev/topics/db/transactions/#savepoints

그래서 주어진 무언가 같이하십시오 BATCH_ID을하는 것입니다

transaction.auto_commit(False) 
try: 
    for raw_input in streaming_filelikeobject.readline(): 
     product = do_work(raw_input) 
     MyTable(**product).save() 
except SomeFileIOError: 
    transaction.rollback() 
else: 
    transaction.commit() 

또 다른 생각 각 배치의 시작 부분에 할당하십시오.

매우 큰 데이터 세트의 경우, 재고 관리를 위해 Memcache/Redis와 같은 것을 사용할 수 있습니다.

transaction.auto_commit(False) 
try: 

    for raw_input in streaming_filelikeobject.readline(): 
     product = do_work(raw_input) 
     if redis_conn.sadd("my_input_set", product['some_unique_id']): 
      MyTable(**product).save() 

except SomeFileIOError: 
    transaction.rollback() 
else: 
    transaction.commit() 

.sadd()는 요소가 레디 스 세트에 이미 존재하지 않는 경우는 true를 반환하는 레디 스 명령입니다.

참고 사항 장고 트랜잭션 메소드 서명이 권한이 없을 수 있으므로이 정보를 내 머리 상단에 입력하고 있습니다.

관련 문제