Skip to content

파이썬 라이브러리 shelve #
Find similar titles

shelve 라이브러리에 대한 대부분의 내용은 아래 링크에서 확인 가능하다.

https://docs.python.org/3/library/shelve.html

shelve #

shelve 라이브러리에서 제공하는 shelve는 key - value 형식으로 동작하는 JSON, dictionary 와 같이 동작하는 자료 객체이다. shelve의 가장 큰 특징 중 하나는, shelve를 열어 생성한 결과는 사용자가 정의한 파일에 저장되어 프로세스가 종료어 메모리가 지워지더라도, 다음에 실행할 때 이전에 저장한 결과를 확인할 수 있다는 점이다. 또한 database에서는 db가 지원하는 format으로만 자료를 저장하는 것과는 달리 별다른 작업을 하지 않고도 내부적으로 Pickle을 이용하여 객체 자체를 저장하고 불러오기가 가능하다.

shelve 의 설치 #

shelve는 python 2, 3 대 버전을 전부 지원하며 python에 built-in 되어 있어 특별히 설치가 필요 없이 아래와 같이 호출하여 간단하게 불러올 수 있다.

 import shelve

# shelve의 사용법 shelve는 다음과 같이 간단하게 객체를 생성할 수 있다.

 db = shelve.open(filename)

위와 같이 생성하면 처음 만들어질 경우 filename 경로에 파일이 생성되며 만약 기존에 작업된 내용이 저장되어 있을 경우에는 이전에 저장한 결과를 불러온다. 인스턴스가 생성되면 db 변수를 이용해서 새로운 key-value를 입력하거나 변경, 삭제를 할 수 있다.

>>> db = shelve.open(filename)
>>> db['a'] = 1  # a라는 변수에 새로운 값 할당
>>> print (db['existed_value'])  # 이전에 저장된 값 호출
"existed_data"
>>> db['existed_value'] = "update_data" # 기존의 key에 값 변경
>>> print (db['existed_value']) 
"updated_data"
>>> import datetime
>>> db["updaate_date"] = datetime.datetime.now()  # shelve에 객체 저장가능
>>> print(db["updaate_date"])
datetime.datetime(2017, 11, 23, 15, 36, 20, 278241)
>>> del db['a']  # 기존에 key = 'a' 데이터 삭제
>>> db.close()

shelve를 사용시 주의해야할 사항 #

close() #

shelve의 동작은 dictionary와 거의 동일하게 진행되나, 기본적으로 file 기반으로 동작하며, 최종 결과는 파일에 기록된다. shelve의 동작 특성상, 매 추가, 수정 삭제 동작 때마다 파일을 읽고 쓰지 않으며 close() 시 파일에 기록된다. 그러므로 close() 함수를 이용하여, shelve를 닫지 않을 경우 변경사항이 파일에 정상적으로 기록되지 않을 수 있으므로 주의해야 한다.

대부분의 경우 python에서 함수가 끝날 대에 내부 local 변수들에 대한 close() 작업을 수행한다. 하지만 close() 되지 않는 가장 대표적인 사례로 exception으로 인해 동작 중인 프로세스가 강제 종료되는 경우이다. 이때는 python이 중도 정지되므로 파이썬 내부에서 close() 처리를 하지 못하기 때문에 저장 중인 데이터 중 일부가 소실될 수 있다.

db.close() #파일 종료

혹은 with 예약어를 이용하여 종료되는 상황을 방지할수 있다.

 with shelve.open( filename ) as db:
    # db 변경 코드

동시접근 지원 안함 #

대부분의 database에서는 동시 접근에 대한 critical section 을 방지할 수 있는 기능을 지원한다. 하지만 shelve의 경우 해당 기능을 지원하지 않는다. 그러므로 동시에 2개 이상의 process에서 동일한 shelve를 수정할 경우 critical section로 인해 문제가 생길 수 있다. (python 3 documate에 보면 해당 문제가 있다고 명시되어 있다)

그러므로 shelve를 이용하여 정보를 읽고 쓰는 기능을 구현할 때에는, 한 번에 여러 개의 프로세스에서 동일한 파일에 접근을 하는지, 접근을 할 경우 read, write 문제는 어떻게 되는지 (일반적으로 단순 조회 (read) 인 경우에는 critical section 문제에서 비교적 자유롭다), 만약 critical section 문제가 발생하더라도 시스템에 큰 문제가 되는지 사전에 확인해야 한다. 또한 실제 개발을 진행할 때에도 오래 종작하는 task가 shelve를 계속 열어두지 않도록 관리를 해야 한다.

 Critical Section Problem (동시 가변성 문제) : 일반적으로 운영체제(특히 유닉스)에서 공유된 메모리에 서로 다른 두 task가 접근할 때 생길 수 있는 문제로 서로 다른 프로세스가 하나의 자원을 동시에 접근하여 수정할 경우 예기지 못한 문제가 발생하는 것을 말한다. 예를 들어 web이나 thread 등을 이용하여 서로 다른 task_a, task_b 가 동일 shelve db_file에서 동시에 수정 작업을 진행한다면

   - task_a(db_file 읽어옴) -> 
   - task_a(읽은 db_file 수정작업 진행 중 - 저장 X) -> 
   - task_b(db_file 읽어옴) -> 
   - task_b(읽은 db_file 수정작업 진행 중 - 저장 X) -> 
   - task_a(작업 완료후 db_file 저장) -> 
   - task_b(작업 완료후 db_file 저장 - task_a 가 저장했던 내용 위에 덮어씌움 )

위에서와 같이 task_b로 인해 task_a의 작업이 전부 사라지는 결과가 발생할 수 있다. 대부분의 database에서는 mutex, semaphore 을 응용하여 동시 접근성 에 대한 기능을 지원한다.

속도 문제 #

shelve는 기본적으로 파일 기반으로 동작하기 때문에 매번 shelve를 열고 닫을 때마다, 파일을 읽고 수정사항을 기존 파일 위에 덮어쓴다. 그러므로 공식 문서에서는 shelve에서 올릴 데이터는 cache 수준의 적은 데이터만 올리길 권장하며, 데이터가 너무 클 경우 shelve에 접근할 때마다 load/write 시간이 오래 거나 정상적인 동작이 안 할 수 있음을 경고한다.

Suggested Pages #

0.0.1_20210630_7_v33