Python peewee 사용 경험

11174 단어 Pythonpeewee
본 논문 의 사용 사례 는 python 2.7 을 바탕 으로 이 루어 진 것 이다.
다음 내용 은 모두 개인 이 peewee 를 사용 한 경험 과 만 나 는 구덩이 로 너무 많은 기본 적 인 조작 과 관련 되 지 않 습 니 다.그래서 peewee 를 사용 해 본 적 이 없어 서 먼저 문 서 를 읽 을 수 있 습 니 다.
정확성 과 범위 가 높 아 질 필요 가 있 으 니 새로운 문제 에 부 딪 히 면 토론 을 환영 합 니 다.
소개
Peewee는 간단 하고 가 벼 운 Python ORM 이다.
  • 간단 하고 가 볍 고 표 현 력 이 풍부 한 ORM
  • python 버 전 2.6+와 3.2+
  • 지원
  • 지원 데이터 베 이 스 는 sqlite,my sql 및 postgresql
  • 을 포함한다.
  • 플레이 하우스 모듈 에 실 용적 인 확장 을 포함 합 니 다
  • 한 마디 로 하면 peewee 는 개인 이나 기업 의 중 소형 프로젝트 에 충분히 대응 할 수 있 는 Model 층 으로 손 이 쉽 고 기능 이 강하 다.
    2.기본 적 인 사용 방법
    
    from peewee import *
    
    db = SqliteDatabase('people.db')
    class BaseModel(Model):
      class Meta:
        database = db # This model uses the "people.db" database.
    
    class Person(BaseModel):
      name = CharField()
      birthday = DateField()
      is_relative = BooleanField()  
    
    기본 적 인 사용 방법,문서 읽 기 추천-quickstart
    3.자세 추천
    다음은 제 가 사용 하 는 과정 에서 의 경험 과 만 났 던 구 덩이 를 소개 하 겠 습 니 다.여러분 들 이 peewee 를 잘 사용 할 수 있 도록 도와 주 셨 으 면 좋 겠 습 니 다.
    3.1 연결 데이터베이스
    데이터 베 이 스 를 연결 할 때 playhouse 의 db 를 추천 합 니 다.url 모듈.db_url 의 connect 방법 은 들 어 오 는 URL 문자열 을 통 해 데이터베이스 연결 을 생 성 할 수 있 습 니 다.
    3.1.1 connect(url, **connect_params)
    들 어 오 는 url 문자열 을 통 해 데이터베이스 인 스 턴 스 를 만 듭 니 다.
    url 모양:
  • mysql://user:passwd@ip:port/my_db 는 로 컬 MySQL 의 my 를 만 들 것 입 니 다.db 데이터베이스 인 스 턴 스(will create a MySQL Database instance)
  • mysql+pool://user:passwd@ip:port/my_db?charset=utf8&max_connections=20&stale_timeout=300 로 컬 MySQL 의 my 를 만 듭 니 다.db 의 연결 풀,최대 연결 수 는 20In a multi-threaded application, up to max_connections will be opened. Each thread (or, if using gevent, greenlet) will have it's own connection.,시간 초과 시간 은 300 초(will create a PooledMySQL Database instance)
  • 메모:charset 기본 값 은 utf 8 입 니 다.emoji 를 지원 하려 면 charset 를 utf8mb 4 로 설정 하고 데이터 베 이 스 를 만 들 때 문자 집합 설정 이 올 바 르 도록 합 니 다CREATE DATABASE mydatabase CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;。지원 하 는 schemes:
  • apsw: APSWDatabase
  • mysql: MySQLDatabase
  • mysql+pool: PooledMySQLDatabase
  • postgres: PostgresqlDatabase
  • postgres+pool: PooledPostgresqlDatabase
  • postgresext: PostgresqlExtDatabase
  • postgresext+pool: PooledPostgresqlExtDatabase
  • sqlite: SqliteDatabase
  • sqliteext: SqliteExtDatabase
  • sqlite+pool: PooledSqliteDatabase
  • sqliteext+pool: PooledSqliteExtDatabase
  • 3.1.2 추천 자세
    
    from playhouse.db_url import connect
    
    from dock.common import config
    
    # url: mysql+pool://root:[email protected]:3306/appmanage?max_connections=300&stale_timeout=300
    mysql_config_url = config_dict.get('config').get('mysql').get('url')
    db = connect(url=mysql_config_url)
    
    자세 한 내용 은 공식 문서 로 이동 하 십시오.db-url
    3.2 연결 탱크 의 사용
    peewee 의 연결 탱크 입 니 다.사용 할 때 연결 을 명시 적 으로 닫 아야 합 니 다.다음은 왜 그런 지,마지막 으로 추천 하 는 사용법 을 제시 해 구덩이 에 들 어가 지 않도록 하 겠 습 니 다.
    3.2.1 왜 연결 을 명시 적 으로 닫 아야 합 니까?
    Connections will not be closed exactly when they exceed their stale_timeout. Instead, stale connections are only closed when a new connection is requested.
    여기 인용공식 문서 의 알림.대체로"시간 초과 연결 은 자동 으로 닫 히 지 않 고 새로운 요청 이 있 을 때 만 닫 힌 다"고 말 했다.여기 서 request 는'웹 프레임 워 크 처리 요청',peewee 소스 세 션 을 말 합 니 다.
    
    def _connect(self, *args, **kwargs):
      while True:
        try:
          # Remove the oldest connection from the heap.
          ts, conn = heapq.heappop(self._connections) # _connections      list(pool)
          key = self.conn_key(conn)
        except IndexError:
          ts = conn = None
          logger.debug('No connection available in pool.')
          break
        else:
          if self._is_closed(key, conn):
            # This connecton was closed, but since it was not stale
            # it got added back to the queue of available conns. We
            # then closed it and marked it as explicitly closed, so
            # it's safe to throw it away now.
            # (Because Database.close() calls Database._close()).
            logger.debug('Connection %s was closed.', key)
            ts = conn = None
            self._closed.discard(key)
          elif self.stale_timeout and self._is_stale(ts):
            # If we are attempting to check out a stale connection,
            # then close it. We don't need to mark it in the "closed"
            # set, because it is not in the list of available conns
            # anymore.
            logger.debug('Connection %s was stale, closing.', key)
            self._close(conn, True)
            self._closed.discard(key)
            ts = conn = None
          else:
            break
      if conn is None:
        if self.max_connections and (
            len(self._in_use) >= self.max_connections):
          raise ValueError('Exceeded maximum connections.')
        conn = super(PooledDatabase, self)._connect(*args, **kwargs)
        ts = time.time()
        key = self.conn_key(conn)
        logger.debug('Created new connection %s.', key)
    
      self._in_use[key] = ts #            dict
      return conn
    
    
    pool 라 이브 러 리 의_connect 방법 코드 에 따 르 면 데이터베이스 연결 을 만 들 때마다 연결 인 스 턴 스 가 시간 을 초과 하 는 지 확인 합 니 다.하지만 주의해 야 할 점:사용 중인 데이터베이스 연결 인 스 턴 스(in_use dict 의 데이터베이스 연결 인 스 턴 스)는 데이터베이스 연결 을 만 들 때 시간 초과 여 부 를 검사 하지 않 습 니 다.
    이 코드 에서 연결 인 스 턴 스 를 만 들 때마다_connections(pool)에서 인 스 턴 스 를 가 져 오고 있 으 면 시간 초과 여 부 를 판단 하기 때 문 입 니 다.없 으 면 새로 만 들 겠 습 니 다.
    그러나 사용 중인 데이터베이스 연결 은 _connections 에 있 지 않 기 때문에 데이터베이스 연결 인 스 턴 스 를 만 들 때마다 사용 중인 데이터베이스 연결 인 스 턴 스 가 시간 을 초과 하 는 지 확인 하지 않 았 습 니 다.
    연결 탱크 인 스 턴 스 를 호출 하 는 방법 만 있 습 니 다.이 방법 을 실행 한 후에 야 사용 한 연결 인 스 턴 스 를_close (pool)로 돌려 놓 을 수 있 습 니 다.
    
    def _close(self, conn, close_conn=False):
      key = self.conn_key(conn)
      if close_conn:
        self._closed.add(key)
        super(PooledDatabase, self)._close(conn) #           
      elif key in self._in_use:
        ts = self._in_use[key]
        del self._in_use[key]
        if self.stale_timeout and self._is_stale(ts):  #        _in_use          
          logger.debug('Closing stale connection %s.', key)
          super(PooledDatabase, self)._close(conn)  #     ,       
        else:
          logger.debug('Returning %s to pool.', key)
          heapq.heappush(self._connections, (ts, conn)) #       ,   pool 
    
    
    3.2.2 연결 을 명시 적 으로 닫 지 않 으 면 발생 하 는 문제
    만약 에 _connections 방법 을 호출 하지 않 으 면 사용 후의 데이터베이스 연결 은 계속 닫 히 지 않 습 니 다(두 가지 의미:pool 로 돌아 가 거나 데이터베이스 연결 을 닫 습 니 다).그러면 두 가지 문제 가 발생 할 수 있 습 니 다.
    1.매번 새 데이터베이스 연결 입 니 다.pool 에 데이터베이스 연결 인 스 턴 스 가 없 기 때 문 입 니 다.약간의 병발 량 이 있 으 면 되 돌아 오 는 오류 가 발생 할 수 있 습 니 다_close.
    2.MySQL 에 도 timeout 이 있 습 니 다.연결 이 오랫동안 요청 되 지 않 으 면 MySQL Server 가 이 연결 을 닫 습 니 다.그러나 peewee 가 만 든 연결 인 스 턴 스(뒤에 왜 만 들 었 는 지 설명 합 니 다)는 MySQL Server 가 닫 혔 는 지 모 르 고 이 연결 을 통 해 데 이 터 를 요청 하면 돌아 갑 니 다Exceeded maximum connections."오류 입 니 다.공식 문서 에 의 하면
    3.2.3 추천 자세
    그래서 데이터 베 이 스 를 조작 할 때마다 연결 인 스 턴 스 를 닫 습 니 다.
    용법 1:사용 with
    
    def send_rule():
      with db.execution_context():
      # A new connection will be opened or, if using a connection pool,
      # pulled from the pool of available connections. Additionally, a
      # transaction will be started.
        for user in get_all_user():
          user_id = user['id']
          rule = Rule(user_id)
          rule_dict = rule.slack_rule(index)
          .....do something.....
    
    
    용법 2:Flask hook 사용
    
    @app.before_request
    def _db_connect():
      database.connect()
    #
    # This hook ensures that the connection is closed when we've finished
    # processing the request.
    @app.teardown_request
    def _db_close(exc):
      if not database.is_closed():
        database.close()
    #
    #
    #       :
    from playhouse.flask_utils import FlaskDB
    from dock_fastgear.model.base import db
    #
    app = Flask(__name__)
    FlaskDB(app, db) #             (       http://docs.peewee-orm.com/en/latest/peewee/playhouse.html?highlight=Flask%20DB#flask-utils)
    자세 한 내용 은 공식 문서 로 이동 하 십시오.pool-apis
    3.3 처리 조회 결과
    이곳 에는 큰 구덩이 가 없 지만 두 가지 주의 가 필요 하 다.
    우선,검색 결 과 는 모두 이 Model 의 object 입 니 다.dict 가 아 닙 니 다.결 과 를 dict 로 만 들 려 면Error 2006: “MySQL server has gone away모듈 의 도구 방법 으로 전환 해 야 합 니 다.playhouse 그 다음으로from playhouse.shortcuts import model_to_dict방법 은 하나의 기록 만 되 돌려 준다.
    3.3.1 추천 자세
    
    from playhouse.shortcuts import model_to_dict
    from model import HelloGitHub
    
    def read_from_db(input_vol):
      content_list = []
      category_object_list = HelloGitHub.select(HelloGitHub.category).where(HelloGitHub.vol == input_vol)\
        .group_by(HelloGitHub.category).order_by(HelloGitHub.category)
    
      for fi_category_object in category_object_list:
        hellogithub = HelloGitHub.select()\
          .where((HelloGitHub.vol == input_vol)
              & (HelloGitHub.category == fi_category_object.category))\
          .order_by(HelloGitHub.create_time)
        for fi_hellogithub in hellogithub:
          content_list.append(model_to_dict(fi_hellogithub))
      return content_list
    
    
    4.흔히 볼 수 있 는 오류 와 해결 방법
    4.1 'buffer' object has no attribute 'translate'
  • 오류 정보:"'buffer'object has no attribute'translate'"
  • 장면:BlobField 필드 에 zlib copress 압축 데이터 저장
  • 해결 방법:pymysql 버 전 을 0.6.7 보다 작 게 지정 해 야 합 니 다.그렇지 않 으 면 오류 가 발생 합 니 다
  • 레 퍼 런 스
  • 4.2 Can't connect to MySQL server Lost connection to MySQL server during query
  • 오류 정보:MySQL 서버 에 연결 할 수 없 음 쿼 리 중 에 MySQL 서버 에 연결 할 수 없 음
  • 장면:RDS 에 데이터 삽입
  • 해결 방법:요청 한 연결 수가 너무 많아 RDS 가 설정 한 연결 수 에 도 달 했 기 때문에 RDS 연결 수 를 높 여야 합 니 다
  • 레 퍼 런 스
  • 이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기