파이썬코딩

NoSQL 데이터 저장소

일부 데이터베이스는 관계형 데이터베이스가 아니므로 SQL을 지원하지 않습니다. 이는 매우 큰 데이터 세트를 처리하거나, 보다 유연한 데이터 정의를 허용하거나, 사용자 지정 데이터 작업을 지원하기 위해 작성되었습니다. 이들은 집합적으로 NoSQL(이전에는 SQL이 없었으나 이제는 SQL뿐만 아니라 덜 대립한다는 의미)로 분류되었습니다.

 

dbm 제품군

DBM 포맷은 NoSQL이 만들어지기 훨씬 전에 존재했다. 키 밸류 스토어로, 웹 브라우저와 같은 응용 프로그램에 내장되어 다양한 설정을 유지합니다. DBM 데이터베이스는 다음과 같은 면에서 파이썬 사전과 같습니다.

• 키에 값을 할당할 수 있으며, 자동으로 디스크에 있는 데이터베이스에 저장됩니다. • 키에서 값을 얻을 수 있습니다.

다음은 간단한 예입니다. 다음 open() 메서드에 대한 두 번째 인수는 읽으려면 'r', 쓰려면 'w', 둘 다의 경우 'c'로 파일이 존재하지 않을 경우 파일을 만듭니다.

 

>>> import dbm
>>> db = dbm.open('definitions', 'c') 

키-값 쌍을 만들려면 사전과 마찬가지로 키에 값을 할당하면 됩니다.

 

>>> db['mustard'] = 'yellow'

    >>> db['ketchup'] = 'red'

    >>> db['pesto'] = 'green'

 

잠시 멈추고 지금까지 보여드린 내용을 확인해 보겠습니다.

 

 >>> len(db)

    3

    >>> db['pesto']

    b'green'

 

닫았다가 다시 열어 실제로 저장했는지 확인합니다.

 

 >>> db.close()

    >>> db = dbm.open('definitions', 'r')

    >>> db['mustard']

    b'yellow'

 

키와 값은 바이트로 저장됩니다. 데이터베이스 오브젝트 DB를 반복할 수는 없지만 len()을 사용하여 키 수를 얻을 수 있습니다. 사전에서와 같이 get() 및 setdefault()가 작동합니다.

 

Memcached 

memcached는 빠른 메모리 내 키 값 캐시 서버입니다. 종종 데이터베이스 앞에 놓이거나 웹 서버 세션 데이터를 저장하는 데 사용됩니다. Linux 및 OS X용 및 Windows용 버전을 다운로드할 수 있습니다. 이 섹션을 사용하려면 memcached 서버와 Python 드라이버가 필요합니다.

Python 드라이버에는 여러 가지가 있습니다. Python 3에서 작동하는 드라이버는 python3 memcached이며 다음 명령을 사용하여 설치할 수 있습니다.

 

$ pip install python-memcached

이를 사용하려면 memcached 서버에 연결하고, 그런 다음 다음을 수행할 수 있습니다.

• 키 값 설정 및 가져오기

• 값의 증가 또는 감소

• 키 삭제

데이터가 영구적이지 않고 이전에 작성한 데이터가 사라질 수 있습니다. 이것은 memcached에 내재되어 있습니다. 캐시 서버이기 때문입니다. 오래된 데이터를 카드화하여 메모리 부족을 방지합니다.

여러 memcached 서버에 동시에 연결할 수 있습니다. 다음 예에서는 같은 컴퓨터에 있는 사람과 대화하고 있습니다.

 

>>> import memcache
>>> db = memcache.Client(['127.0.0.1:11211']) >>> db.set('marco', 'polo')
True
>>> db.get('marco')
'polo'
>>> db.set('ducks', 0)
True
>>> db.get('ducks')
0
>>> db.incr('ducks', 2)
2
>>> db.get('ducks')
2 

레디스

Redis는 데이터 구조 서버입니다. memcached와 마찬가지로 Redis 서버의 모든 데이터는 메모리에 맞아야 합니다(데이터를 디스크에 저장할 수 있는 옵션이 있습니다). memc ac aced와 달리 Redis는 다음을 수행할 수 있습니다.

• 안정성 및 재시작을 위해 데이터를 디스크에 저장

• 이전 데이터 유지

• 단순한 문자열보다 더 많은 데이터 구조 제공

Redis 데이터 유형은 Python과 거의 일치하며, Redis 서버는 하나 이상의 Python 애플리케이션이 데이터를 공유하는 데 유용한 매개체가 될 수 있다. 나는 그것이 매우 유용하다는 것을 알았기 때문에 여기에서 약간의 추가 커버리지를 할 가치가 있다.

파이썬 드라이버 redis-py는 온라인 문서뿐만 아니라 GitHub에 소스 코드와 테스트를 가지고 있다. 다음 명령을 사용하여 설치할 수 있습니다.

 

  • $ pip install redis
  • Redis 서버 자체의 설명서가 좋습니다. 로컬 컴퓨터에 네트워크 닉네임 localhost를 사용하여 Redis 서버를 설치하고 시작하는 경우 다음 섹션에서 pro ing을 사용할 수 있습니다.

 

 

  • Strings 
  • 단일 값을 갖는 키는 Redis 문자열입니다. 간단한 파이썬 데이터 유형이 자동으로 
  • 변환됩니다. 일부 호스트(기본값: localhost) 및 포트(de 오류: 6379)에서 Redis 
  • 서버에 연결합니다.
  • >>> import redis
  • >>> conn = redis.Redis()
  • redis.Redis('localhost') 또는 redis.Redis('localhost', 6379)도 같은 결과를 냈을 것이다.

모든 키 나열(현재 없음):

  >>> conn.keys('*')

    []

 

단순 문자열(키 'secret', 정수(키 '캐럿') 및 플로트(키 'fever') 설정:

 

  >>> conn.set('secret', 'ni!')

    True

    >>> conn.set('carats', 24)

    True

    >>> conn.set('fever', '101.5')

    True

 

키로 값을 다시 가져옵니다.

 

  >>> conn.get('secret')

    b'ni!'

    >>> conn.get('carats')

    b'24'

    >>> conn.get('fever')

    b'101.5'

 

여기서 setnx() 메서드는 키가 없는 경우에만 값을 설정합니다.

 

>>> conn.setnx('secret', 'icky-icky-icky-ptang-zoop-boing!') 

False 

이미 '비밀'을 정의했기 때문에 실패했습니다.

 

>>> conn.get('secret') 

b'ni!'

getset() 메서드는 이전 값을 반환하고 동시에 새 값으로 설정합니다.

 

 >>> conn.getset('secret', 'icky-icky-icky-ptang-zoop-boing!')

    b'ni!'

 

너무 앞서가지 맙시다. 효과가 있던가요?

  >>> conn.get('secret')

    b'icky-icky-icky-ptang-zoop-boing!'

 

이제 getrange()를 사용하여 하위 문자열을 가져옵니다(파이썬에서와 같이 오프셋 0=start, -1=end).

 

>>> conn.getrange('secret', -6, -1) 

b'boing!'

setrange()를 사용하여 하위 문자열을 교체합니다(영점 기반 오프셋 사용).

 

   >>> conn.setrange('secret', 0, 'ICKY')

    32

    >>> conn.get('secret')

    b'ICKY-icky-icky-ptang-zoop-boing!'

 

그런 다음 mset()을 사용하여 여러 키를 한 번에 설정합니다.

 

    >>> conn.mset({'pie': 'cherry', 'cordial': 'sherry'})

    True

 

mget()을 사용하여 두 개 이상의 값을 동시에 가져옵니다.

 

>>> conn.mget(['fever', 'carats']) 

[b'101.5', b'24']

삭제()를 사용하여 키 삭제:

 

  >>> conn.delete('fever')

    True

 

incr() 또는 incrbyfloat() 명령을 사용하여 증가시키고 decr()을 사용하여 감소시킵니다.

 

  >>> conn.incr('carats')

    25

    >>> conn.incr('carats', 10)

    35

    >>> conn.decr('carats')

    34

    >>> conn.decr('carats', 15)

    19

    >>> conn.set('fever', '101.5')

    True

    >>> conn.incrbyfloat('fever')

    102.5

    >>> conn.incrbyfloat('fever', 0.5)

    103.0

 

디크르비플로트가 없습니다. 열을 낮추려면 음의 증분을 사용합니다.

 

>>> conn.incrbyfloat('fever', -2.0) 

101.0 

목록

재지정 목록에는 문자열만 포함할 수 있습니다. 이 목록은 처음 삽입할 때 작성됩니다. lpush()를 사용하여 처음에 삽입합니다.

 

    >>> conn.lpush('zoo', 'bear')

    1

 

처음에 두 개 이상의 항목을 삽입합니다.

 >>> conn.lpush('zoo', 'alligator', 'duck')

    3

삽입()을 사용하여 값 앞 또는 뒤에 삽입:

 >>> conn.linsert('zoo', 'before', 'bear', 'beaver')

    4

    >>> conn.linsert('zoo', 'after', 'bear', 'cassowary')

    5

lset()을 사용하여 오프셋에 삽입(목록이 이미 존재해야 함):

>>> conn.lset('zoo', 2, 'marmoset') 

True 

rpush()를 사용하여 끝에 삽입합니다.

 

>>> conn.rpush('zoo', 'yak') 

6 

lindex()를 사용하여 오프셋의 값을 가져옵니다.

>>> conn.lindex('zoo', 3) 

b'bear'

lrange()(0 ~ -1)를 사용하여 오프셋 범위의 값을 가져옵니다.

 

   >>> conn.lrange('zoo', 0, 2)

    [b'duck', b'alligator', b'marmoset']

 

ltrim()으로 목록을 트리밍하고 오프셋 범위에만 유지합니다.

>>> conn.ltrim('zoo', 1, 4) 

True 

lrange()를 사용하여 값의 범위를 가져옵니다(모두에 대해 0 ~ -1 사용).

 

>>> conn.lrange('zoo', 0, -1) 

[b'alligator', b'marmoset', b'bear', b'cassowary']

이 장에서는 Redis 목록과 게시-구독을 사용하여 구현할 수 있는 방법을 보여줍니다.

작업 대기열

 

Hashes 

Redis 해시는 Python 사전과 유사하지만 문자열만 포함할 수 있습니다. 그러므로, 여러분은 깊은 내피 구조를 만들 수 없고 오직 한 단계만 깊이 들어갈 수 있습니다. 다음은 노래라는 Redis 해시를 만들고 재생하는 예입니다.

hmset()을 사용하여 해시 송에서 do 및 re 필드를 한 번에 설정합니다.

 

>>> conn.hmset('song', {'do': 'a deer', 're': 'about a deer'}) 

True 

 

hset()을 사용하여 해시의 단일 필드 값을 설정합니다.

>>> conn.hset('song', 'mi', 'a note to follow re') 

1 

hget()을 사용하여 필드 값 가져오기:

 

>>> conn.hget('song', 'mi') 

b'a note to follow re'

hmget()을 사용하여 여러 필드 값을 가져옵니다.

 

  >>> conn.hmget('song', 're', 'do')

    [b'about a deer', b'a deer']

 

hkeys()를 사용하여 해시의 모든 필드 키를 가져옵니다.

 

>>> conn.hkeys('song') 

[b'do', b're', b'mi']

hval()을 사용하여 해시의 모든 필드 값을 가져옵니다.

 

  >>> conn.hvals('song')

    [b'a deer', b'about a deer', b'a note to follow re']

 

hlen()을 사용하여 해시의 필드 수를 가져옵니다.

 

>>> conn.hlen('song') 

3 

hgetall()을 사용하여 해시의 모든 필드 키 및 값을 가져옵니다.

 

>>> conn.hgetall('song') 

{b'do': b'a deer', b're': b'about a deer', b'mi': b'a note to follow re'} 

hsetnx()를 사용하여 해당 키가 없는 필드를 설정합니다.

 

 >>> conn.hsetnx('song', 'fa', 'a note that rhymes with la')

    1

파이썬코드 SQL 표현식 언어

다음 레벨 업은 SQLlchemy의 SQL 표현 언어입니다. 다양한 작업을 위한 SQL 생성 기능을 소개합니다. 표현식 언어는 하위 엔진 계층보다 더 많은 SQL 방언 차이를 처리합니다. 관계형 데이터베이스 애플리케이션에 편리한 중간 접근 방식이 될 수 있습니다.

다음은 동물원 테이블을 만들고 채우는 방법입니다. 다시 말하지만, 이것들은 단일 프로그램의 연속된 조각들입니다.

가져오기 및 연결은 이전과 동일합니다.

 

>>> import sqlalchemy as sa
>>> conn = sa.create_engine('sqlite://') 

동물원 테이블을 정의하기 위해 SQL 대신 표현식 언어 중 일부를 사용하기 시작합니다.

 

  >>> meta = sa.MetaData()

    >>> zoo = sa.Table('zoo', meta,

  •     ...      sa.Column('critter', sa.String, primary_key=True),
  •  
  •     ...      sa.Column('count', sa.Integer),
  •  
  •     ...      sa.Column('damages', sa.Float)
  •     ...    )
  •     >>> meta.create_all(conn)
  •  

앞의 예에서 여러 줄 통화의 괄호를 확인하십시오. 표() 메서드의 구조는 표 구조와 일치합니다. 표에 세 개의 열이 있는 것처럼 표() 메서드 호출의 괄호 안에 열()에 대한 세 개의 호출이 있습니다.

한편, zoo는 SQL 데이터베이스 세계와 파이썬 데이터 구조 세계를 연결하는 마법의 객체입니다.

표현 언어 함수가 더 많은 데이터를 삽입합니다.

 

 ... conn.execute(zoo.insert(('bear', 2, 1000.0)))

    <sqlalchemy.engine.result.ResultProxy object at 0x1017ea910>

    >>> conn.execute(zoo.insert(('weasel', 1, 2000.0)))

    <sqlalchemy.engine.result.ResultProxy object at 0x1017eab10>

    >>> conn.execute(zoo.insert(('duck', 10, 0)))

    <sqlalchemy.engine.result.ResultProxy object at 0x1017eac50>

 

그런 다음 SELECT 문을 만듭니다(zoo.select()). 예를 들어, SELECT * FROM ZOO가 일반 SQL에서 수행하는 것과 같이 동물원 개체가 나타내는 테이블에서 모든 것을 선택합니다.

 

>>> result = conn.execute(zoo.select()) 

마지막으로 다음과 같은 결과를 얻습니다.

>>> rows = result.fetchall()
>>> print(rows)
[('bear', 2, 1000.0), ('weasel', 1, 2000.0), ('duck', 10, 0.0)] 

객체-상대 매퍼

마지막 섹션에서 zoo 객체는 SQL과 파이썬 간의 중간 수준 연결이었다. SQLlchemy의 최상위 계층에서 ORM(Object-Relational Mapper)은 SQL 표현 언어를 사용하지만 실제 데이터베이스 메커니즘을 보이지 않게 하려고 합니다. 클래스를 정의하면 ORM이 데이터베이스로 데이터를 가져오거나 내보내는 방법을 처리합니다. "객체-관계형 맵퍼"라는 복잡한 구절 뒤에 숨겨진 기본 개념은 여러분이 코드에 있는 객체를 참조할 수 있고, 따라서 관계형 데이터베이스를 사용하면서 파이썬이 동작하는 방식에 근접할 수 있다는 것입니다.

 

동물원 클래스를 정의해서 ORM에 연결하겠습니다. 이번에는 SQLite에서 zoo.db 파일을 사용하도록 하여 ORM이 작동했는지 확인합니다.

 

앞의 두 절에서와 같이, 다음에 나오는 토막글은 실제로 설명으로 구분된 하나의 프로그램입니다. 이해가 안 가더라도 걱정하지 마세요. SQLArchemy 문서에는 모든 세부 사항이 포함되어 있습니다. 이 내용은 복잡해질 수 있습니다. 이 장에서 논의한 접근 방식 중 자신에게 적합한 방법을 결정할 수 있도록 이 작업을 수행하는 데 얼마나 많은 작업이 필요한지 파악해 주시기 바랍니다.

초기 가져오기는 동일하지만 이번에는 다른 것도 필요합니다.

 

>>> import sqlalchemy as sa
>>> from sqlalchemy.ext.declarative import declarative_base 

여기, 우리는 다음과 같은 연결을 만듭니다.

 

 >>> conn = sa.create_engine('sqlite:///zoo.db')

 

이제 SQLArchemy의 ORM에 대해 알아보겠습니다. Zoo 클래스를 정의하고 해당 속성을 테이블 열과 연결합니다.

 

>>> Base = declarative_base() >>> class Zoo(Base): 

  •     ...      __tablename__ = 'zoo'
  •  
  •     ...      critter = sa.Column('critter', sa.String, primary_key=True)
  •  
  •     ...      count = sa.Column('count', sa.Integer)
  •  
  •     ...      damages = sa.Column('damages', sa.Float)
  •  
  • ...  def __init__(self, critter, count, damages):
  •     ...          self.critter = critter
  •  
  •     ...          self.count = count
  •  
  •     ...          self.damages = damages
  •  
  • ...  def __repr__(self):
  • ...  return "<Zoo({}, {}, {})>".format(self.critter, self.count, self.damages) 
  •  
  • 다음 행은 데이터베이스와 테이블을 마법처럼 작성합니다.
  • >>> Base.metadata.create_all(conn)

  • 그런 다음 파이썬 개체를 만들어 데이터를 삽입할 수 있습니다. ORM은 이러한 것들을 관리한다.
  • 내부:
  •  
  • >>> first = Zoo('duck', 10, 0.0)
  •     >>> second = Zoo('bear', 2, 1000.0)
  •     >>> third = Zoo('weasel', 1, 2000.0)
  •     >>> first
  •     <Zoo(duck, 10, 0.0)>
  •  
  • 다음으로, 우리는 ORM이 우리를 SQL 랜드로 데려가게 합니다. 데이터베이스와 대화하기 위한 세션을 만듭니다.
  •  
  • . >>> from sqlalchemy.orm import sessionmaker >>> Session = sessionmaker(bind=conn)
    >>> session = Session()
  • 세션 내에서, 우리는 우리가 만든 세 개의 객체를 데이터베이스에 작성합니다. add() 함수는 하나의 객체를 추가하고 add_all()은 목록을 추가합니다.
  • .
  •   >>> session.add(first)
  •     >>> session.add_all([second, third])
  •  

  • 마지막으로, 우리는 모든 것을 완료하도록 강요해야 합니다.
  • >>> session.commit()

효과가 있던가요? 현재 디렉터리에 zoo.db 파일을 만들었습니다. 사용할 수 있습니다.

확인할 명령줄 sqlite3 프로그램:

 

  • $ sqlite3 zoo.db
    SQLite version 3.6.12
    Enter ".help" for instructions
    Enter SQL statements terminated with a ";" sqlite> .tables
    zoo
    sqlite> select * from zoo; 
  • duck|10|0.0

bear|2|1000.0

 

 weasel|1|2000.0

 

이 섹션의 목적은 ORM이 무엇이고 높은 수준에서 어떻게 작동하는지 보여주기 위한 것이다. SQLlchemy의 작성자가 전체 자습서를 작성했습니다. 이 내용을 읽은 후 다음 중 필요에 가장 적합한 수준을 결정하십시오.

 

• 이전 SQLite 섹션에서와 같이 일반 DB-API

 

• SQLArchemy 엔진룸

 

• SQLArchemy 표현 언어

 

• SQLChemy ORM

 

SQL의 복잡성을 피하기 위해 ORM을 사용하는 것은 자연스러운 선택인 것 같습니다. 하나 쓸까요? 어떤 사람들은 ORM을 피해야 한다고 생각하지만, 다른 사람들은 이 비판이 지나치다고 생각한다. 누가 옳든, ORM은 추상화입니다. 그리고 모든 추상화들은 어느 순간 무너집니다. 그것들은 새어나갑니다. ORM이 원하는 작업을 수행하지 않는 경우 SQL에서 ORM의 작동 방식과 해결 방법을 모두 파악해야 합니다. 인터넷 밈을 빌리려면: 어떤 사람들은 어떤 문제에 직면했을 때, "알아요, ORM을 써야겠어요."라고 생각합니다. 이제 그들은 두 가지 문제를 안고 있습니다. ORM은 거의 사용하지 않으며 대부분 간단한 애플리케이션에 사용합니다. 응용 프로그램이 그렇게 간단한 경우 스트레이트 SQL(또는 SQL 표현식 언어)을 사용할 수도 있습니다.

 

또는 데이터 집합과 같은 간단한 것을 시도할 수 있습니다. SQL, JSON 및 CSV 스토리지를 위한 간단한 ORM을 제공하는 SQLLchemy는 SQL, JSON 및 CSV 스토리지를 제공합니다.

 

파이썬코드 Db-api sqlite mysql

DB-API 

 

API(응용 프로그램 프로그래밍 인터페이스)는 일부 서비스에 액세스하기 위해 호출할 수 있는 함수 집합입니다. DB-API는 관계형 데이터베이스에 액세스하기 위한 Python의 표준 API입니다. 이를 사용하여 각 데이터베이스에 대해 별도의 프로그램을 작성하는 대신 여러 종류의 관계형 데이터베이스에서 작동하는 단일 프로그램을 작성할 수 있습니다. 그것은 자바의 JDBC나 펄의 dbi와 비슷하다.

주요 기능은 다음과 같습니다.

연결하다

데이터베이스에 연결합니다. 사용자 이름, 암호, 서버 주소 등의 인수를 포함할 수 있습니다.

 

커서가 있는

쿼리를 관리할 커서 개체를 만듭니다. 사형 집행 집행 집행 집행 집행 집행 집행 집행 집행 집행 집행 집행 집행 집행 집행 집행 집행 집행.

데이터베이스에 대해 하나 이상의 SQL 명령을 실행합니다.

fetchone() , fetchmany() 및 fetchall() 실행에서 결과를 가져옵니다.

다음 절의 Python 데이터베이스 모듈은 DB-API를 준수하며, 종종 확장과 세부 사항의 일부 차이점이 있습니다.

 

SQLite

SQLite는 우수하고 가벼운 오픈 소스 관계형 데이터베이스입니다. 표준 파이썬 라이브러리로 구현되며 데이터베이스를 일반 파일에 저장합니다. 이 파일들은 ma ch chines 및 운영 체제 간에 이동 가능하므로 SQLite는 단순한 관계형 데이터베이스 애플리케이션을 위한 매우 휴대성이 뛰어난 솔루션이 됩니다. MySQL 또는 Postgre만큼 완벽한 기능은 아닙니다.SQL은 지원하지만 여러 명의 동시 사용자를 관리합니다. 웹 브라우저, 스마트폰 및 기타 응용 프로그램은 SQLite를 내장 데이터베이스로 사용합니다.

사용 또는 작성할 로컬 SQLite 데이터베이스 파일에 대한 연결()로 시작합니다. 이 파일은 부모가 다른 서버에 있는 테이블로 사용하는 디렉토리와 같은 데이터베이스와 동일합니다. 특수 문자열 ':memory:'는 메모리에만 데이터베이스를 만듭니다. 이 문자열은 빠르고 테스트에 유용하지만 프로그램이 종료되거나 컴퓨터가 다운되면 데이터가 손실됩니다.

 

다음 예로, 번창하는 길가 애완 동물원의 사업을 관리하기 위해 Enterprise.db라는 데이터베이스와 테이블 동물원(table zoo)을 만들어 보겠습니다. 테이블 열은 다음과 같습니다.

생물의 가변 길이 문자열 및 기본 키

수를 세다

이 동물에 대한 현재 재고의 정수 개수

손해

현재 동물과 인간의 상호작용으로 인한 손실의 액수입니다.

 

>>> import sqlite3
>>> conn = sqlite3.connect('enterprise.db') >>> curs = conn.cursor()
>>> curs.execute('''CREATE TABLE zoo 

        (critter VARCHAR(20) PRIMARY KEY,

         count INT,

         damages FLOAT)''')

<sqlite3.Cursor object at 0x1006a22d0>

Python의 삼중따옴표는 SQL 쿼리와 같은 긴 문자열을 만들 때 유용합니다.

 

이제 동물원에 동물을 추가하세요.

 

 >>> curs.execute('INSERT INTO zoo VALUES("duck", 5, 0.0)')

    <sqlite3.Cursor object at 0x1006a22d0>

    >>> curs.execute('INSERT INTO zoo VALUES("bear", 2, 1000.0)')

    <sqlite3.Cursor object at 0x1006a22d0>

 

자리 표시자를 사용하여 데이터를 더 안전하게 삽입할 수 있습니다.

 

  >>> ins = 'INSERT INTO zoo (critter, count, damages) VALUES(?, ?, ?)'

    >>> curs.execute(ins, ('weasel', 1, 2000.0))

    <sqlite3.Cursor object at 0x1006a22d0>

 

이번에는 SQL에 물음표 3개를 사용하여 3개의 값을 삽입한 다음 이 3개의 값을 목록으로 실행() 함수에 전달할 계획임을 나타냅니다. 보험 계약자는 인용과 같은 지루한 세부 사항을 처리합니다. SQL 주입으로부터 사용자를 보호합니다. SQL 주입은 웹에서 일반적으로 시스템에 악의적인 SQL 명령을 삽입하는 외부 공격입니다.

이제, 우리가 우리의 모든 동물들을 다시 꺼낼 수 있는지 봅시다.

 

>>> curs.execute('SELECT * FROM zoo') <sqlite3.Cursor object at 0x1006a22d0> >>> rows = curs.fetchall()
>>> print(rows) 

[('duck', 5, 0.0), ('bear', 2, 1000.0), ('weasel', 1, 2000.0)] 

다시 불러오죠. 하지만 숫자대로 정렬합니다.

 

  >>> curs.execute('SELECT * from zoo ORDER BY count')

    <sqlite3.Cursor object at 0x1006a22d0>

    >>> curs.fetchall()

    [('weasel', 1, 2000.0), ('bear', 2, 1000.0), ('duck', 5, 0.0)]

 

이봐, 우린 내림차순으로 원했어.

   >>> curs.execute('SELECT * from zoo ORDER BY count DESC')

    <sqlite3.Cursor object at 0x1006a22d0>

    >>> curs.fetchall()

    [('duck', 5, 0.0), ('bear', 2, 1000.0), ('weasel', 1, 2000.0)]

 

어떤 종류의 동물이 가장 비용이 많이 드나요?

 

 >>> curs.execute('''SELECT * FROM zoo WHERE

    ...     damages = (SELECT MAX(damages) FROM zoo)''')

    <sqlite3.Cursor object at 0x1006a22d0>

    >>> curs.fetchall()

    [('weasel', 1, 2000.0)]

 

여러분은 곰들이라고 생각했을 것입니다. 항상 실제 데이터를 확인하는 것이 가장 좋습니다.

SQLite를 떠나기 전에 정리를 해야 합니다. 연결과 커서를 연 경우 작업이 완료되면 커서를 닫아야 합니다.

 

    >>> curs.close()

    >>> conn.close()

 

MySQL

MySQL은 매우 널리 사용되는 오픈 소스 관계형 데이터베이스입니다. SQLite와 달리 실제 서버이므로 클라이언트가 네트워크상의 다른 장치에서 액세스할 수 있습니다.

MysqlDB는 가장 인기 있는 MySQL 드라이버였지만 아직 파이썬 3으로 포팅되지는 않았다. 표 8-3에는 파이썬에서 MySQL에 액세스하는 데 사용할 수 있는 드라이버가 나와 있습니다.

표 8-3. MySQL 드라이버

 

MySQL Connector PYMySQL
oursql 

Link 

http://bit.ly/mysql-cpdg 

https://github.com/petehunt/ PyMySQL/ 

http://pythonhosted.org/oursql/ 

Pypi package Import as 

mysql-connector- mysql.connector python 

Notes 

Requires the MySQL C client libraries. 

 

PostgreSQl

링크

http://bit.ly/mysql-cpdg

https://github.com/petehunt/ PyMySQL/

http://pythonhosted.org/oursql/

Pypi 패키지 가져오기 위치

mysql-sql.mysql.mysql

메모들

MySQL C 클라이언트 라이브러리가 필요합니다.

Pymysql usql

pymysql

usql

포스트그레SQL은 MySQL보다 여러 면에서 더 많은 이점을 제공하는 완전한 기능의 오픈 소스 관계형 데이터베이스입니다. 표 8-4는 Python 드라이버에 액세스하는 데 사용할 수 있는 드라이버를 보여줍니다.

포스트그레SQL 드라이버

 

가장 인기 있는 드라이버는 psycopg2이지만 Postgre를 설치해야 한다.SQL 클라이언트 라이브러리.

 

SQLArchemy

SQL은 모든 관계형 데이터베이스에 대해 완전히 동일하지는 않으며 DB-API는 지금까지만 지원합니다. 각 데이터베이스는 그 특징과 철학을 반영하는 특정한 방언을 구현한다. 많은 도서관들이 이런 차이점들을 어떻게든 메우려고 노력한다. 가장 널리 사용되는 데이터베이스 간 파이썬 라이브러리는 SQLArchemy입니다.

그것은 표준 도서관에는 없지만, 많은 사람들에 의해 잘 알려져 있고 사용되고 있습니다. 다음 명령을 사용하여 시스템에 설치할 수 있습니다.

 

$ pip install sqlalchemy

• 가장 낮은 수준은 데이터베이스 연결 풀, SQL 명령 실행 및 결과 반환을 처리합니다. DB-API에 가장 가깝습니다.

 

• 다음은 SQL 표현 언어인 Pythonic SQL Builder입니다.

 

• 가장 높은 계층은 SQL 식을 사용하는 ORM(Object Relational Model) 계층입니다.

 

언어 및 관계형 데이터 구조와 응용 프로그램 코드를 바인딩합니다.

계속 진행하면서 이러한 수준의 용어가 무엇을 의미하는지 이해하게 될 것입니다. SQLArchemy는 이전 절에 설명된 데이터베이스 드라이버와 함께 작동합니다. 드라이버를 가져올 필요가 없습니다. SQLLCemy에 제공한 초기 연결 문자열이 드라이버를 결정합니다. 이 문자열은 다음과 같습니다.

 

  • dialect + driver :// user : password @ host : port / dbname

이 문자열에 입력한 값은 다음과 같습니다.

사투리를 쓰다

데이터베이스 유형

운전사의

해당 데이터베이스에 사용할 특정 드라이버

사용자 및 암호

데이터베이스 인증 문자열

숙주와 항구

데이터베이스 서버의 위치(: 이 서버의 표준 포트가 아닌 경우에만 필요)

dbname

서버에서 처음 연결할 데이터베이스

 

  • Table 8-5 lists the dialects and drivers.
    Table 8-5. SQLAlchemy connection

dialect 

sqlite

mysql

mysql

mysql

postgresql

postgresql

driver 

pysqlite (or omit) mysqlconnector pymysql
oursql psycopg2 pypostgresql 

엔진 층

먼저, 기본 DB- API 기능보다 조금 더 낮은 수준의 SQLlchemy를 사용해 보겠습니다.

파이썬에 이미 내장된 SQLite를 사용해 보겠습니다. SQLite에 대한 연결 문자열이 호스트, 포트, 사용자 및 암호를 건너뜁니다. dbname은 데이터베이스를 저장하는 데 사용할 파일을 SQLite에 알려줍니다. dbname을 생략하면 SQLite는 메모리에 데이터베이스를 작성합니다. dbname이 슬래시(/)로 시작하는 경우 컴퓨터의 절대 파일 이름입니다(예: Windows의 C:\\). 그렇지 않으면 현재 디렉토리와 관련이 있습니다.

다음 세그먼트는 설명을 위해 여기에서 분리된 한 프로그램의 모든 부분입니다.

먼저 필요한 것을 가져오셔야 합니다. 다음은 문자열 sa를 사용하여 SQLLCemy 메서드를 참조할 수 있는 가져오기 별칭의 예입니다. 주로 sa가 sqlalchemy보다 훨씬 쉽게 입력되기 때문에 이 작업을 수행합니다.

 

>>> import sqlalchemy as sa

데이터베이스에 연결하고 메모리에 데이터베이스에 대한 저장소 만들기(인수 문자열)

'sqlite://:memory:'도 작동합니다.

 

>>> conn = sa.create_engine('sqlite://') 

다음과 같은 세 개의 열로 구성된 zoo라는 데이터베이스 테이블을 만듭니다.

 

>>> conn.execute('''CREATE TABLE zoo 

...

...

...

<sqlalchemy.engine.result.ResultProxy object at 0x1017efb10>

 

conn.execute()를 실행하면 ResultProxy라는 SQLLCemy 개체를 반환합니다. 너는 곧 그것을 어떻게 해야 할지 알게 될 것이다.

그나저나, 데이터베이스 표를 만들어 본 적이 없다면 축하드립니다. 버킷 리스트에서 하나를 체크하세요.

이제 비어 있는 새 테이블에 세 가지 데이터 세트를 삽입합니다.

 

    >>> ins = 'INSERT INTO zoo (critter, count, damages) VALUES (?, ?, ?)'

    >>> conn.execute(ins, 'duck', 10, 0.0)

    <sqlalchemy.engine.result.ResultProxy object at 0x1017efb50>

    >>> conn.execute(ins, 'bear', 2, 1000.0)

    <sqlalchemy.engine.result.ResultProxy object at 0x1017ef090>

    >>> conn.execute(ins, 'weasel', 1, 2000.0)

    <sqlalchemy.engine.result.ResultProxy object at 0x1017ef450>

 

그런 다음 데이터베이스에 방금 입력한 모든 내용을 요청하십시오.

    >>> rows = conn.execute('SELECT * FROM zoo')

 

SQLArchemy에서 행은 목록이 아니라 직접 인쇄할 수 없는 특별한 ResultProxy입니다.

 

>>> print(rows)
<sqlalchemy.engine.result.ResultProxy object at 0x1017ef9d0> 

그러나 목록처럼 반복할 수 있으므로 한 번에 다음 행을 얻을 수 있습니다.

 

>>> for row in rows: ... print(row) ...
('duck', 10, 0.0) ('bear', 2, 1000.0) ('weasel', 1, 2000.0) 

앞에서 보신 SQLite DB-API 예제와 거의 동일합니다. 한 가지 장점은 맨 위에 있는 데이터베이스 드라이버를 가져올 필요가 없다는 것입니다. SQLArchemy는 연결 문자열에서 이를 알아냈습니다. 연결 문자열을 변경하면 이 코드가 다른 유형의 데이터베이스로 이동될 수 있습니다. 또 다른 장점은 SQLlchemy의 연결 풀링이며, 이 풀링은 설명서 사이트에서 확인할 수 있습니다.

 

 

파이썬코드 피클을 사용하여 직렬화

데이터 구조를 파일에 저장하는 것을 직렬화라고 합니다. JSON과 같은 형식을 사용하려면 파이썬 프로그램의 모든 데이터 유형을 직렬화하기 위해 일부 사용자 지정 변환기가 필요할 수 있습니다. 파이썬은 특별한 바이너리 형식으로 객체를 저장하고 복원할 수 있는 피클 모듈을 제공한다.

날짜/시간 객체를 만났을 때 JSON이 어떻게 정신을 잃었는지 기억하십니까? 피클에 대한 확률 없음:

 

>>> import pickle
>>> import datetime
>>> now1 = datetime.datetime.utcnow()
>>> pickled = pickle.dumps(now1)
>>> now2 = pickle.loads(pickled)
>>> now1
datetime.datetime(2014, 6, 22, 23, 24, 19, 195722) >>> now2
datetime.datetime(2014, 6, 22, 23, 24, 19, 195722) 

피클은 당신의 클래스나 오브젝트에서도 작동한다. 문자열로 처리될 때 문자열 'tiny'를 반환하는 Tiny라는 작은 클래스를 정의합니다.

 

>>> import pickle
>>> class Tiny():
... def __str__(self): ... return 'tiny' ...
>>> obj1 = Tiny() 

>>> obj1
<__main__.Tiny object at 0x10076ed10>
>>> str(obj1)
'tiny'
>>> pickled = pickle.dumps(obj1)
>>> pickled b'\x80\x03c__main__\nTiny\nq\x00)\x81q\x01.' >>> obj2 = pickle.loads(pickled)
>>> obj2
<__main__.Tiny object at 0x10076e550>
>>> str(obj2)
'tiny' 

절인 것은 물체 obj1로부터 만들어진 절인 2진법 끈이다. 우리는 그것을 객체 obj2로 다시 변환하여 obj1의 복사본을 만들었습니다. 덤프()를 사용하여 파일에 피클하고 로드()를 사용하여 파일에서 피클을 해제합니다.

 

피클은 파이썬 개체를 만들 수 있기 때문에 이전 섹션에서 설명한 것과 동일한 보안 경고 잉그가 적용됩니다. 신뢰하지 않는 것을 풀지 마라.

 

구조화된 이진 파일

일부 파일 형식은 특정 데이터 구조를 저장하기 위해 설계되었지만, 규격 데이터베이스도 NoSQL 데이터베이스도 아니다. 다음 절에서는 그 중 일부를 제시합니다.

 

스프레드시트

스프레드시트, 특히 Microsoft Excel은 널리 사용되는 이진 데이터 형식입니다. 스프레드시트를 CSV 파일에 저장할 수 있는 경우 앞서 설명한 표준 CSV 모듈을 사용하여 스프레드시트를 읽을 수 있습니다. 이진 xls 파일이 있는 경우 xlrd는 읽고 쓰기를 위한 타사 패키지입니다.

 

HDF5

HDF5는 다차원 또는 계층적 숫자 데이터를 위한 이진 데이터 형식입니다. 대용량 데이터셋(기가바이트 ~ 테라바이트)에 대한 빠른 랜덤 액세스가 일반적인 요구 사항인 과학 분야에서 주로 사용됩니다. 어떤 경우에는 HDF5가 데이터베이스의 좋은 대안이 될 수 있지만, 어떤 이유로 HDF5는 비즈니스 세계에서 거의 알려져 있지 않습니다. 충돌하는 쓰기로부터 데이터베이스를 보호할 필요가 없는 WORM(Write Once/Read Many) 애플리케이션에 가장 적합합니다. 다음은 유용한 몇 가지 모듈입니다.

 

h5py는 완전 저수준 인터페이스입니다. 설명서 및 코드를 읽습니다.

 

PyTables는 데이터베이스와 유사한 기능을 가진 좀 더 높은 레벨입니다. 설명서와 코드를 읽습니다.

이 두 가지 모두 부록 C에서 파이썬의 과학적 적용 측면에서 논의된다. 여기서 말하는 것은 대량의 데이터를 저장 및 검색해야 하는 경우 일반적인 데이터베이스 솔루션뿐만 아니라 외부 솔루션을 고려할 의사가 있는 경우입니다. 좋은 예는 HDF5 형식의 다운로드 가능한 노래 데이터가 있는 Million Song 데이터 세트입니다

 

관계형 데이터베이스

관계형 데이터베이스는 약 40년 밖에 되지 않았지만 컴퓨팅 세계 어디에서나 볼 수 있습니다. 여러분은 거의 틀림없이 한 번 혹은 여러 번 그들을 상대해야 할 것입니다. 그러면 다음과 같은 혜택을 누릴 수 있습니다.

 

• 여러 동시 사용자의 데이터 액세스

• 해당 사용자에 의한 손상 방지

• 효율적인 데이터 저장 및 검색 방법

• 스키마에 의해 정의되고 제약에 의해 제한되는 데이터

• 다양한 유형의 데이터에 걸친 관계를 찾기 위한 결합

• 선언적(필수적) 질의 언어: SQL(구조화된 쿼리 언어)

 

이것들은 서로 다른 종류의 데이터들 사이의 관계를 표의 형태로 보여주기 때문에 관계형이라고 불린다. 예를 들어, 앞의 메뉴 예에서는 각 품목과 가격 사이에 관계가 있습니다.

 

테이블은 스프레드시트와 유사한 행과 열의 그리드입니다. 테이블을 만들려면 테이블 이름을 지정하고 열의 순서, 이름 및 유형을 지정하십시오. 결측 데이터(null이라고 함)를 허용하도록 열을 정의할 수 있지만 각 행에는 동일한 열이 있습니다. 메뉴 예제에서는 판매되는 각 품목에 대해 하나의 행으로 테이블을 만들 수 있습니다. 각 품목에는 가격에 대한 열을 포함하여 동일한 열이 있습니다.

 

열 또는 열 그룹은 일반적으로 테이블의 기본 키이며 해당 값은 테이블에서 고유해야 합니다. 이렇게 하면 테이블에 동일한 데이터를 두 번 이상 추가할 수 없습니다. 이 키는 쿼리 중 빠른 검색을 위해 인덱싱됩니다. 색인은 책 색인처럼 작동하기 때문에 특정 행을 빨리 찾을 수 있습니다.

각 테이블은 디렉토리 내의 파일처럼 상위 데이터베이스 내에 있습니다. 두 단계의 위계질서가 상황을 조금 더 잘 정리하도록 도와줍니다.

 

예, 데이터베이스라는 단어는 서버, 테이블 컨테이너 및 여기에 저장된 데이터로 여러 가지 방법으로 사용됩니다. 모든 항목을 동시에 참조하는 경우 데이터베이스 서버, 데이터베이스 및 데이터라고 부르는 것이 도움이 될 수 있습니다.

 

키가 아닌 일부 열 값으로 행을 찾으려면 해당 열에 보조 인덱스를 정의합니다. 그렇지 않은 경우, 데이터베이스 서버는 테이블 검색을 수행해야 합니다. 즉, 일치하는 열 값을 찾기 위해 모든 행을 무차별적으로 검색합니다.

테이블은 외부 키를 사용하여 서로 연관될 수 있으며 열 값은 이러한 키에 변형될 수 있습니다.

 

SQL

SQL은 API나 프로토콜이 아니라 선언적 언어입니다. 어떻게 하느냐 보다는 원하는 것을 말합니다. 이것은 관계형 데이터베이스의 보편적인 언어입니다. SQL 쿼리는 클라이언트가 데이터베이스 서버로 보내는 텍스트 문자열로, 이 문자열로 수행할 작업을 결정합니다.

다양한 SQL 표준 정의가 존재했지만, 모든 데이터베이스 공급업체는 자체적인 수정과 확장을 추가하여 많은 SQL 방언들을 만들어냈다. 데이터를 관계형 데이터베이스에 저장하면 SQL이 어느 정도 휴대성을 제공합니다. 그러나 방언 및 운영상의 차이로 인해 데이터를 다른 유형의 데이터베이스로 이동하기가 어려울 수 있습니다.

SQL 문에는 두 가지 주요 범주가 있습니다.

DDL(데이터 정의 언어)

테이블, 데이터베이스 및 사용에 대한 작성, 삭제, 제약 조건 및 사용 권한 처리

DML(데이터 조작 언어)

데이터 삽입, 선택, 업데이트 및 삭제 처리 표 8-1은 기본 SQL DDL 명령을 나열합니다.

표 8-1. 기본 SQL DDL 명령

 

Operation 

Create a database
Select current database
Delete a database and its tables Create a table
Delete a table
Remove all rows from a table 

SQL pattern 

CREATE DATABASE dbname
USE dbname
DROP DATABASE dbname CREATE TABLE tbname ( coldefs ) DROP TABLE tbname 

TRUNCATE TABLE tbname 

SQL example 

CREATE DATABASE d
USE d
DROP DATABASE d
CREATE TABLE t (id INT, count INT) DROP TABLE t 

TRUNCATE TABLE t 

 

왜 대문자는 다 쓰죠? SQL은 대소문자를 구분하지 않지만 코드 검사에서 키워드를 SHOUT하는 것이 전통입니다. 열 이름과 구별하기 위해 사용합니다.

관계형 데이터베이스의 주요 DML 작업은 흔히 CRUD 약어로 알려져 있습니다.

• SQL INSERT 문을 사용하여 작성

• SELECT를 사용하여 읽기

• UPDATE를 사용하여 업데이트

• DELETE를 사용하여 삭제

표 8-2는 SQL DML에 사용할 수 있는 명령을 살펴본다. 표 8-2. 기본 SQL DML 명령

 

Operation 

Add a row 

Select all rows and columns Select all rows, some columns 

Select some rows, some columns 

Change some rows in a column Delete some rows 

 

SQL pattern 

INSERT INTO tbname VALUES( ...) 

SELECT * FROM tbname SELECT cols FROM tbname 

SELECT cols FROM tbname WHERE condition 

UPDATE tbname SET col = value WHERE condition 

DELETE FROM tbname WHERE condition 

SQL example 

INSERT INTO t VALUES(7, 40) 

SELECT * FROM t
SELECT id, count FROM t 

SELECT id, count from t WHERE count > 5 AND id = 9 

UPDATE t SET count=3 WHERE id=5 

DELETE FROM t WHERE count <= 10 OR id = 16 

 

 

 

 

 

 

 

 

 

 

파이썬코드 xml

XML

구분된 파일은 행(줄)과 열(줄 안의 필드)의 두 차원만 전달합니다. 프로그램 간에 데이터 구조를 교환하려면 계층, 시퀀스, 세트 및 기타 구조를 텍스트로 인코딩하는 방법이 필요합니다.

XML은 법안에 가장 적합한 마크업 형식이다. 이 샘플 menu.xml 파일에서와 같이 태그를 사용하여 데이터를 구분합니다.

 

  •   <?xml version="1.0"?>
  •     <menu>

  •       <breakfast hours="7-11">
  •         <item price="$6.00">breakfast burritos</item>
  •         <item price="$4.00">pancakes</item>
  •  

   </breakfast>

      <lunch hours="11-3">

        <item price="$5.00">hamburger</item>

      </lunch>

      <dinner hours="3-10">

        <item price="8.00">spaghetti</item>

      </dinner>

    </menu>

 

다음은 XML의 몇 가지 중요한 특성입니다.

• 태그는 < 문자로 시작합니다. 이 샘플의 태그는 메뉴, 아침, 점심, 그리고

디너와 아이템.

• 공백은 무시됩니다.

• 일반적으로 <메뉴>와 같은 시작 태그 다음에 다른 내용이 나온 다음 </menu>와 같은 최종 일치 끝 태그가 뒤따른다.

• 태그는 모든 수준으로 다른 태그에 중첩될 수 있습니다. 이 예에서 항목 태그는 아침, 점심 및 저녁 태그의 하위 항목이며, 차례로 메뉴의 하위 항목입니다.

• 시작 태그 내에서 선택적 속성이 발생할 수 있습니다. 이 예에서 가격은 품목의 속성입니다.

• 태그에는 값이 포함될 수 있습니다. 이 예제에서는 두 번째 아침 식사용 팬케이크와 같은 값이 각 품목에 있습니다.

• 어떤 물건에 값이나 자식 태그가 없는 경우, 그것은 <thing>과 같이 시작 태그와 끝 태그가 아닌 <thing/>와 같은 닫힘 각도 괄호 바로 앞에 슬래시를 포함시켜 단일 태그로 표현할 수 있다.

• 데이터를 저장할 위치(속성, 가치, 하위 태그)를 선택하는 것은 다소 어렵다. 예를 들어, 마지막 항목 태그를 <품목 가격="$8.00" 식품="food"/">으로 작성할 수 있었다.

XML은 종종 데이터 피드 및 메시지에 사용되며 RSS 및 Atom과 같은 보조 형식을 가집니다. 일부 산업에는 재무 분야와 같은 많은 전문 XML 형식이 있습니다.

XML의 위버 유연성은 접근 방식과 기능이 다른 여러 파이썬 라이브러리에 영감을 주었습니다.

파이썬에서 XML을 구문 분석하는 가장 간단한 방법은 ElementTree를 사용하는 것입니다. 다음은 menu.xml 파일을 구문 분석하고 태그와 속성을 인쇄하는 데 사용할 수 있는 작은 프로그램입니다.

 

  • >>> import xml.etree.ElementTree as et
    >>> tree = et.ElementTree(file='menu.xml')
    >>> root = tree.getroot()
    >>> root.tag
    'menu'
    >>> for child in root:
    ... print('tag:', child.tag, 'attributes:', child.attrib)

... for grandchild in child:
... print('\ttag:', grandchild.tag, 'attributes:', grandchild.attrib) ...
tag: breakfast attributes: {'hours': '7-11'} 

        tag: item attributes: {'price': '$6.00'}

        tag: item attributes: {'price': '$4.00'}

    tag: lunch attributes: {'hours': '11-3'}

        tag: item attributes: {'price': '$5.00'}

    tag: dinner attributes: {'hours': '3-10'}

tag: item attributes: {'price': '8.00'} >>> len(root) # number of menu sections 3
>>> len(root[0]) # number of breakfast items 2 

중첩 목록의 각 요소에 대해 태그는 태그 문자열이고 속성은 해당 특성의 사전입니다. 원소트리는 XML에서 파생된 데이터를 검색하고, 데이터를 mod if ifing하고, XML 파일을 쓰는 다른 많은 방법을 가지고 있습니다. 원소트리 설명서에 자세한 내용이 있습니다.

다른 표준 파이썬 XML 라이브러리는 다음을 포함한다:

xml.dom

JavaScript 개발자에게 익숙한 DOM(Document Object Model)은 웹 문서를 계층 구조로 나타냅니다. 이 모듈은 전체 XML 파일을 메모리에 로드하고 모든 항목에 동일하게 액세스할 수 있도록 합니다.

xml.sax

XML용 단순 API 또는 SAX는 XML을 즉시 구문 분석하므로 모든 것을 한 번에 메모리에 로드할 필요가 없습니다. 따라서 매우 큰 XML 스트림을 처리해야 하는 경우 이 방법을 선택하는 것이 좋습니다.

 

HTML

엄청난 양의 데이터가 웹의 기본 문서 형식인 HTML(Hypertext Markup Language)로 저장된다. 문제는 HTML 규칙을 따르지 않는 경우가 너무 많아서 구문 분석하기가 어려울 수 있다는 것입니다. 또한 HTML의 대부분은 데이터를 교환하기 보다는 출력을 포맷하기 위한 것이다. 이 장은 꽤 잘 정의된 데이터 형식을 설명하기 위한 것이기 때문에 HTML에 대한 논의를 다음포스팅에서 분리했습니다.

 

JSON

자바스크립트 객체 표기법(JSON)은 그것의 자바스크립트 기원을 넘어 매우 대중적인 데이터 교환 형식이 되었다. JSON 형식은 자바스크립트의 하위 집합이며 종종 합법적인 파이썬 구문이기도 하다. Python에 매우 적합하기 때문에 프로그램 간의 데이터 교환에 적합합니다. 웹 개발을 위한 JSON의 예는 다음포스팅에서 많이 볼 수 있습니다.

 

XML 모듈의 다양성과 달리 JSON 모듈은 단 하나이며, gettable 이름은 json입니다. 이 프로그램은 데이터를 JSON 문자열로 인코딩(덤프)하고 JSON 문자열을 데이터로 다시 디코딩(로드)합니다. 다음 예에서는 이전 XML 예제의 데이터를 포함하는 파이썬 데이터 스트럭 튜어를 구축해 보겠습니다.

 

>>>menu=\
... {
... "breakfast": { 

    ...

    ...

    ...

    ...

    ...

    ...

    ... "lunch" : {

...

...

...

...

...

... "dinner": {

...

...

...

...

...

... }

.

"hours": "7-11",

"items": {

}, 

"breakfast burritos": "$6.00",

"pancakes": "$4.00"

}

"hours": "11-3",

"items": {

        "hamburger": "$5.00"

"hours": "3-10",

"items": {

        "spaghetti": "$8.00"

} } 

그런 다음 덤프()를 사용하여 데이터 구조(메뉴)를 JSON 문자열(메뉴_json)로 인코딩합니다.

 

>>> import json
>>> menu_json = json.dumps(menu)
>>> menu_json
'{"dinner": {"items": {"spaghetti": "$8.00"}, "hours": "3-10"}, "lunch": {"items": {"hamburger": "$5.00"}, "hours": "11-3"}, "breakfast": {"items": {"breakfast burritos": "$6.00", "pancakes": "$4.00"}, "hours": "7-11"}}' 

 

이제 로드()를 사용하여 JSON 문자열 메뉴_json을 파이썬 데이터 구조(메뉴2)로 다시 전환해 보겠습니다.

 

   >>> menu2 = json.loads(menu_json)

    >>> menu2

    {'breakfast': {'items': {'breakfast burritos': '$6.00', 'pancakes':

    '$4.00'}, 'hours': '7-11'}, 'lunch': {'items': {'hamburger': '$5.00'},

    'hours': '11-3'}, 'dinner': {'items': {'spaghetti': '$8.00'}, 'hours': '3-10'}}

 

menu와 menu2는 둘 다 키와 값이 같은 사전입니다. 표준 사전에서 항상 그렇듯이 키를 받는 순서도 다릅니다.

 

여기에 설명된 대로 날짜/시간( 다음포스팅의 "달력 및 시계"에 자세히 나와 있음)과 같은 개체를 포함하여 일부 개체를 인코딩하거나 디코딩하는 동안 예외가 발생할 수 있습니다.

 

>>> import datetime
>>> now = datetime.datetime.utcnow()
>>> now
datetime.datetime(2013, 2, 22, 3, 49, 27, 483336)
>>> json.dumps(now)
Traceback (most recent call last):
# ... (deleted stack trace to save trees)
TypeError: datetime.datetime(2013, 2, 22, 3, 49, 27, 483336) is not JSON serializable 

이 문제는 JSON 표준에서 날짜 또는 시간 유형을 정의하지 않기 때문에 발생할 수 있습니다. 사용자가 날짜 또는 시간 유형을 처리하는 방법을 정의해야 합니다. 날짜 시간을 문자열 또는 epoch 값과 같이 JSON이 이해하는 것으로 변환할 수 있습니다(다음포스팅에 나와 있습니다).

 

>>> now_str = str(now)
>>> json.dumps(now_str)
'"2013-02-22 03:49:27.483336"'
>>> from time import mktime
>>> now_epoch = int(mktime(now.timetuple())) >>> json.dumps(now_epoch)
'1361526567' 

날짜/시간 값이 정상적으로 변환된 데이터 유형 중간에 발생할 수 있는 경우 이러한 특수 변환을 수행하는 것이 귀찮을 수 있습니다. 상속을 사용하여 JSON 인코딩 방법을 수정할 수 있습니다. 상속은 다음포스팅의 "상속"에 설명되어 있습니다. 파이썬의 JSON 설명서는 JSON을 데드 플레이하게 만드는 복잡한 숫자에 대한 예를 제공한다. 날짜/시간에 맞게 수정해 보겠습니다.

 

>>> class DTEncoder(json.JSONEncoder): 

 

>>> json.dumps(now, cls=DTEncoder)

'1361526567'

def default(self, obj):
# isinstance() checks the type of obj if isinstance(obj, datetime.datetime): 

return int(mktime(obj.timetuple()))
# else it's something the normal decoder knows: return json.JSONEncoder.default(self, obj) 

...

>>> json.dumps(now, cls=DTEncoder)

'1361526567'

 

새 클래스 DTENCoder는 JSONENCoder의 하위 클래스 또는 하위 클래스입니다. 날짜 시간 처리를 추가하려면 기본() 메서드를 재정의하기만 하면 됩니다. 상속을 수행하면 다른 모든 항목이 상위 클래스에서 처리됩니다.

isinstance() 함수는 개체 obj가 datetime.da time 클래스인지 확인합니다. Python의 모든 것은 개체이므로 isinstance()는 어디에서나 작동합니다.

 

>>> type(now)
<class 'datetime.datetime'>
>>> isinstance(now, datetime.datetime) True
>>> type(234)
<class 'int'>
>>> isinstance(234, int)
True
>>> type('hey')
<class 'str'>
>>> isinstance('hey', str)
True 

JSON 및 기타 구조화된 텍스트 형식의 경우 미리 구조에 대해 아무것도 알지 못한 상태에서 파일에서 데이터 구조로 로드할 수 있습니다. 그런 다음 isinstance() 및 type에 적합한 방법을 사용하여 구조를 살펴볼 수 있습니다. 예를 들어 항목 중 하나가 사전인 경우 키(), 값() 및 항목()을 통해 내용을 추출할 수 있습니다.

 

YAML

JSON과 마찬가지로 YAML에는 키와 값이 있지만 날짜 및 시간과 같은 더 많은 데이터 유형을 처리합니다. 표준 파이썬 라이브러리에는 아직 YAML 처리가 포함되어 있지 않으므로, YAML이라는 이름의 타사 라이브러리를 설치해야 합니다. load()는 YAML 문자열을 파이썬 데이터로 변환하지만 dump()는 반대로 변환합니다.

다음 YAML 파일인 mcintyre.yaml에는 캐나다 시인 제임스 맥킨타이어에 대한 정보가 들어 있습니다.

 

 name:

      first: James

      last: McIntyre

    dates:

      birth: 1828-05-25

      death: 1906-03-31

    details:

      bearded: true

      themes: [cheese, Canada]

    books:

      url: http://www.gutenberg.org/files/36068/36068-h/36068-h.htm

    poems:

      - title: 'Motto'

text: |
Politeness, perseverance and pluck,
To their possessor will bring good luck. 

      - title: 'Canadian Charms'

        text: |

Here industry is not in vain,
For we have bounteous crops of grain, 

And you behold on every field
Of grass and roots abundant yield, But after all the greatest charm
Is the snug home upon the farm,
And stone walls now keep cattle warm. 

true, false, on 및 off와 같은 값은 Python Booans로 변환됩니다. 정수와 문자열은 파이썬 등가물로 변환됩니다. 다른 구문은 목록 및 사전 목록을 만듭니다.

 

>>> import yaml
>>> with open('mcintyre.yaml', 'rt') as fin:
>>> text = fin.read()
>>> data = yaml.load(text)
>>> data['details']
{'themes': ['cheese', 'Canada'], 'bearded': True} >>> len(data['poems'])
2 

생성된 데이터 구조는 YAML 파일의 구조와 일치합니다. 이 경우에는 한 단계 이상의 깊이가 있는 위치입니다. 다음 받아쓰기/목록/독재 참조와 함께 두 번째 시의 제목을 얻을 수 있습니다.

 

   >>> data['poems'][1]['title']

    'Canadian Charms'

 

PyYAML은 문자열에서 Python 개체를 로드할 수 있으며 이는 위험합니다. 신뢰하지 않는 YAML을 가져오는 경우 load() 대신 safe_load()를 사용합니다. 항상 safe_load()를 사용하는 것이 좋습니다. 읽기 전쟁은 Ruby on Rails 플랫폼을 어떻게 조작했는지에 대한 설명을 위한 평화입니다.

보안 노트

이 장에 설명된 모든 형식을 사용하여 객체를 파일에 저장한 후 다시 읽을 수 있습니다. 이 프로세스를 악용하여 보안 문제를 일으킬 수 있습니다.

예를 들어, 위키피디아의 10억 likes 페이지에서 다음 XML 조각은 10개의 중첩된 엔터티를 정의하며, 각각 하위 수준을 10배 확장하여 총 10억 개의 확장을 수행합니다.

 

<?xml version="1.0"?>

    <!DOCTYPE lolz [

     <!ENTITY lol "lol">

     <!ENTITY lol1 "&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;">

     <!ENTITY lol2 "&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;&lol1;">

     <!ENTITY lol3 "&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;">

     <!ENTITY lol4 "&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;">

     <!ENTITY lol5 "&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;">

     <!ENTITY lol6 "&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;">

   <!ENTITY lol7 "&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;">

     <!ENTITY lol8 "&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;">

     <!ENTITY lol9 "&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;">

    ]>

    <lolz>&lol9;</lolz>

 

나쁜 소식은: 10억 번의 웃음이 이전 섹션에서 언급된 모든 XML 라이브러리를 날려버릴 것이라는 것이다. 해제된 XML은 이 공격 및 기타 공격과 파이썬 라이브러리의 취약성을 나열합니다. 링크에는 이러한 문제를 방지하기 위해 여러 라이브러리에 대한 설정을 변경하는 방법이 나와 있습니다. 또한 disusedxml 라이브러리를 다른 라이브러리의 보안 프런트엔드로 사용할 수 있습니다.

 

>>> # insecure:
>>> from xml.etree.ElementTree import parse >>> et = parse(xmlfile)
>>> # protected:
>>> from defusedxml.ElementTree import parse >>> et = parse(xmlfile) 

구성 파일

대부분의 프로그램은 다양한 옵션 또는 설정을 제공합니다. 역동적인 것은 그램의 주장으로 제공될 수 있지만, 오래 지속되는 것은 어딘가에 보관될 필요가 있다. 빠르고 더러운 구성 파일 형식을 정의하려는 유혹이 강하지만 저항합니다. 그것은 종종 더러워지지만 그렇게 빠르지는 않다. 작성자 프로그램과 독서자 프로그램(파서라고도 함)을 모두 유지해야 합니다. 이전 섹션에 있는 것을 포함하여 프로그램에 참여할 수 있는 좋은 대안이 있습니다.

여기서는 Windows 스타일의 .ini 파일을 처리하는 표준 구성 파서 모듈을 사용합니다. 이러한 파일에는 키 = 값 정의 섹션이 있습니다. 다음은 최소 설정.cfg 파일입니다.

 

  [english]

    greeting = Hello

    [french]

    greeting = Bonjour

[files]
home = /usr/local
# simple interpolation: bin = %(home)s/bin 

 

다음은 파이썬 데이터 구조로 읽는 코드입니다.

 

>>> import configparser
>>> cfg = configparser.ConfigParser()
>>> cfg.read('settings.cfg')
['settings.cfg']
>>> cfg
<configparser.ConfigParser object at 0x1006be4d0> >>> cfg['french'] 

   <Section: french>

    >>> cfg['french']['greeting']

    'Bonjour'

    >>> cfg['files']['bin']

    '/usr/local/bin'

 

펑시어 보간법을 포함한 다른 옵션을 사용할 수 있습니다. 구성 도구 문서를 참조하십시오. 두 수준보다 깊은 내포가 필요한 경우 YAML 또는 JSON을 사용해 보십시오.

 

기타 교환 형식

이러한 이진 데이터 교환 형식은 일반적으로 XML이나 JSON보다 더 작고 빠릅니다.

 

• MsgPack
• Protocol Buffers 

• Avro
• Thrift 

이진수이기 때문에 텍스트 편집기를 사용하는 사람이 쉽게 편집할 있는 것은 없습니다.