이 블로그는 Web 환경을 이용한 원격 제어 기술에 필요한 지식을 공유 하기 위한 블로그 입니다.
실제 개발과 프로그램 예를 위하여 Raspberry Pi와 Raspberry Pi Pico, ATmega128 보드, Arduino Mega 보드(ATmega2560), WiFi 모듈을 사용 합니다.

mysql-python

MySQL - Python
MySQL(MariaDB) - Python


  • Python에서 SQL 사용하기
    • 이 페이지를 이해하는데 필요한 Python에 대한 기본 지식과 Python를 이용한 Raspberry Pi Webserver에 대한 자료는 "Raspberry Pi 보오드와 Python 언어를 이용한 원격 제어 " 페이지를 참고하기 바랍니다.

      이 페이지에서 별도의 설명이 없는 경우 "MySQL(MariaDB) - phpMyAdmin - Database 관리" 페이지에서 만든 choSampleDB1을 사용하여 설명한다.

    • Python에서 MySQL(MariaDB) 데이터베이스에 연결하기
      • MySQL(MariaDB)을 사용하기위한 "MySQL Connector/Python" 설치하기
        • Python 드라이버를 설치하기 위하여는 Python이 설치되어 있어야 한다.

          참고자료: "Raspberry Pi 에서 Python 사용을 위한 준비"

          Raspberry Pi에는 Python 2와 Python 3가 이미 설치되어 있기 때문에 별도로 Python를 설치 하지 않아도 된다. 만약 필요하다면 최신 Python 버전으로 업그레이드 할 수 있다.

        • 아래와 명령으로 "MySQL Connector/Python"를 설치한다.
        • sudo apt install python3-mysql.connector

        • 아래와 같은 순서로 MySQL Connector/Python이 정상적으로 설치되었는지 확인한다. MySQL 5.7 과 MariaDB 10.1 이후 버전은 보안을 강화하기 위하여 root 계정은 터미널에서 만 접속할 수 있기 때문에 root 권한을 갖는 별도 사용자 계정를 만들고 이 계정으로 접속하여야 한다.
        • python3

          >>> import mysql.connector

          >>> mysql.connector.connect(host='localhost',database='mysql',user='user_name',password='your pass')

          윗 명령의 실행 결과가 아래와 같이 출려되면 정상적으로 Python이 설치된 것이다.

          <mysql.connector.connection.MySQLConnection object at 0x0187AE50>

      • Python 프로그램에서 MySQL(MariaDB) 데이터베이스 연결하기
      • Python 프로그램과 Web 페이지 작성을 위한 폴더 예는 "Python(Flask)를 이용한 Raspberry Pi Webserver" 페이지를 참고 바람.

          아래 프로그램은 Python 프로그램에서 MySQL(MariaDB) 데이터베이스에 연결하는 프로그램 예이다.

          
          # mysql.connector Objects를 import 한다.
          import mysql.connector
          # Error Objects를 import 한다.
          from mysql.connector import Error
          
          # connect() 함수를 사용하여 MySQL(MariaDB)에 연결한다.
          def connect():
              """ Connect to MySQL database """
              conn = None
              try:
                  // host, database, user, password를 자신의 환경에 맞게 설정한다.
                  conn = mysql.connector.connect(host='localhost',
                                                 database='database_name',
                                                 user='user_name',
                                                 password='****')
              // conn.is_connected() Method로 연결 상태를 Check 한다.
              // 만약 정상으로 연결되었으면 print 문의 실행 결과가 콘솔에 출력된다.
              if conn.is_connected():
                  print('Connected to MySQL database')
              // 만약 Error가 발생하면 Error 메세지가 콘솔에 출력된다.
              except Error as e:
                  print(e)
          
              finally:
                  // 마약 현재 Database가 연결된 상태이면 conn.close() Method로 연결을 종료(Close) 한다.
                  if conn is not None and conn.is_connected():
                      conn.close()
          
          if __name__ == '__main__':
              connect()
                  
        • 위에서 작성한 프로그램 테스트하기
          • 윗 프로그램을 connect.py에 저장한다.
          • 아래 명령으로 connect.py를 실행한다.
          • python3 connect.py

            정상으로 프로그램이 실행되면 "Connected to MySQL database" 메세지가 출력된다.

      • MySQLConnection object를 사용하여 MySQL(MariaDB) 데이터베이스에 연결하기
        • 먼저 아래 예와 같이 Database configuration file을 config.ini 이라는 이름으로 만든다.
        • 
          [mysql]
          host = localhost
          database = database_name
          user = user_name
          password =****
                 
        • 다음에 아래 예와 같이 Database configuration을 읽는 python_mysql_dbconfig.py 이라는 이름으로 파일을 만든다.
        • 
          from configparser import ConfigParser
          
          def read_db_config(filename='config.ini', section='mysql'):
              """ Read database configuration file and return a dictionary object
                :param filename: name of the configuration file
                :param section: section of database configuration
                :return: a dictionary of database parameters
              """
              # create parser and read ini configuration file
              parser = ConfigParser()
              parser.read(filename)
          
              # get section, default to mysql
              db = {}
              if parser.has_section(section):
                  items = parser.items(section)
                  for item in items:
                      db[item[0]] = item[1]
              else:
                  raise Exception('{0} not found in the {1} file'.format(section, filename))
              return db
          	    
        • MySQLConnection object를 이용하여 Database에 연결하는 파일을 connect2.py 이라는 이름으로 파일을 만든다.
        • 
          from mysql.connector import MySQLConnection, Error
          from python_mysql_dbconfig import read_db_config
          
          def connect():
              """ Connect to MySQL database """
              db_config = read_db_config()
              conn = None
              try:
                  print('Connecting to MySQL database...')
                  conn = MySQLConnection(**db_config)
          
                  if conn.is_connected():
                      print('Connection established.')
                  else:
                      print('Connection failed.')
          
              except Error as error:
                  print(error)
          
              finally:
                  if conn is not None and conn.is_connected():
                      conn.close()
                      print('Connection closed.')
          
          if __name__ == '__main__':
              connect()
                  
        • 아래 명령으로 Database 연결을 테스트한다.
        • python3 connect2.py

        • Database 연결되면 아래와 같은 메세지가 출력된다.
        • Connecting to MySQL database...

          Connection established.

          Connection closed.


    • Python에서 SQL를 사용하는 예
    • Python는 SQL를 사용하여 데이터베이스를 관리(자료의 검색과 관리 등)한다. SQL에 대하여는 "MySQL(MariaDB) - Basic - SQL"에서 설명하였기 때문에 여기서는 Python에서 데이터베이스에 연결하여 SQL 문을 사용하는 예만 설명한다.

      • Python에서 Database를 Query 하는 순서는 아래와 같다.
        • 먼저 MySQL(MariaDB) 연결하여 MySQLConnection 객체를 만든다.
        • MySQLConnection 객체에서 MySQLCursor 객체를 인스턴스화 한다.
        • cursor를 사용하여 execute() 메소드를 호출하여 조회를 실행한다.
        • fetchone(), fetchmany() 또는 fetchall() 메소드를 사용하여 조회 결과 세트에서 데이터를 페치(fetch)한다.
        • 해당 Object의 close() 메소드를 호출하여 데이터베이스 연결과 커서를 닫는다.
      • fetchone() method를 사용하여 데이터를 Querying 하는 예
        • fetchone() method는 Query 결과에서 열(row)을 Return 한다. Query 결과에 열(row)이 남아있지 않은 경우에는 None을 Return 한다.

          
          from mysql.connector import MySQLConnection, Error
          from python_mysql_dbconfig import read_db_config
          
          def query_with_fetchone():
              try:
                  """ 새로은 MySQLConnection object를 생성하여 Database에 연결한다. """
                  dbconfig = read_db_config()
                  conn = MySQLConnection(**dbconfig)
                  """ MySQLConnection 객체에서 새로운 MySQLCursor 객체를 인스턴스화 한다. """
                  cursor = conn.cursor()
                  """ 원하는 테이블에서 모든 행을 선택하는 쿼리를 실행한다. """
                  cursor.execute("SELECT * FROM productsTable")
          
                  """ fetchone()을 호출하여 쿼리 결과에서 다음 열을 가져온다. """
                  row = cursor.fetchone()
          
                  """ while 루프 블록에서 열의 내용을 표시하고 모든 열이 페치 될 때까지 다음 열로 이동한다. """
                  while row is not None:
                      print(row)
                      row = cursor.fetchone()
          
              except Error as e:
                  print(e)
          
                  """ 해당 객체의 close() 메소드를 호출하여 커서 및 연결 객체를 모두 닫는다. """
              finally:
                  cursor.close()
                  conn.close()
          
          if __name__ == '__main__':
              query_with_fetchone()
                  
      • fetchall() method를 사용하여 데이터를 Querying 하는 예
        • fetchall() method는 테이블의 행 수가 적은 경우 데이터베이스 테이블에서 모든 행을 페치하는데 사용 할 수 있다.

          fetchall() method를 사용하는 예: fetchall.py

      • fetchmany() method를 사용하여 데이터를 Querying 하는 예
        • fetchmany() method는 Query 결과에서 Return 하는 열(row)의 수를 지정 할 수 있다. Query 결과에 열(row)에 열이 남아있자 않은 경우에는 None을 Return 한다.

          fetchmany() method를 사용하는 예: fetchmany.py

      • 테이블에 하나의 열(row)을 삽입하는 예
        • 아래 예는 choSampleDB1 데이터베이스의 customersTable 테이블에 하나의 열(row)을 삽입하는 예 이다.

          customersTable 테이블에 하나의 열(row)을 삽입하는 예: insert-one-row.py

      • 테이블에 여러 열(row)을 삽입하는 예
        • 아래 예는 choSampleDB1 데이터베이스의 customersTable 테이블에 여러 열(row)을 삽입하는 예 이다.

          customersTable 테이블에 하나의 열(row)을 삽입하는 예: insert-multiple-row.py

      • customersTable 테이블의 데이터를 Update 하는 예
        • 아래 예는 choSampleDB1 데이터베이스 customersTable 테이블의 address를 업데이트 하는 예 이다.

          customersTable 테이블의 address를 업데이트 하는 예: update-address.py

      • 테이블에 여러 열(row)을 삭제하는 예
        • 아래 예는 choSampleDB1 데이터베이스의 customersTable 테이블에서 열(row)을 삭제하는 예 이다.

          customersTable 테이블에 하나의 열(row)을 삽입하는 예: delete-row.py


  • Python Web 페이지와 MySQL(MariaDB)
    • Python 웹서버와 MySQL(MariaDB)을 사용하여 웹 브라우저에서 데이터베이스를 관리하는 예이다.

      웹서버와 MySQL(MariaDB)을 사용하여 웹 브라우저에서 데이터베이스를 관리하는 시스템 구성도

      설명을 위하여 이 페이지에서는 choSampleDB1 테이터베이스를 사용한다.

      Web 환경에서 데이터베이스를 관리하는 예를 설명하기 위하여 이 페이지에서는 고객관리, 제품관리, 제품주문 기능을 포함하고 있는 Web server(salesManagement.py) 프로그램과 각각의 기능을 실행하는 Web page(customersTable-py.htm, productsTable-py.htm, order-py.htm)를 작성하였다.

    • 고객정보 입력 웹 페이지
      • 고객정보 입력 웹 페이지 예

      • 아래 예는 고객 명단(customersTable)을 관리하기 위한 Web page 예 이다.
      • customersTable을 관리하기 위한 Web page 예: customersTable-py.htm

      • 아래 예는 고객 명단(customersTable)을 관리하기 위한 Web server 예 이다. 이해하기 쉽게하기 위하여 salesManagement.py에서 customersTable 관련 부분만 분리하였다.
      • customersTable을 관리하기 위한 Web server 예: customersTable.py

        참고: 디렉토리 계층 구조를 /python/templates/ 과 같이 작성하여 python 디렉토리에는 .py 파일을 저장하고 templates 디렉토리에는 .htm 파일을 저장하여야 한다.

      • 실험하기:
        • 아래 예의 명령으로 웹 서버 프로그램(customersTable.py)을 실행한다.
        • python3 customersTable.py

        • 아래 예와 같이 chrome web browser를 이용 하여 Web server에 연결하면 customersTable-py.htm Page가 열린다.
        • http://[RaspberryPi_IP]:2880/

        • 이 폐이지에서 현재 등록되어있는 전화번호를 입력하고 "고객정보 읽기"를 실행하면 데이터베이스에서 고객정보를 자동으로 검색하여 고객정보가 표시된다.
        • 새 고객정보를 입력하고 "고객정보 입력"을 실행하면 새 고객정보가 등록(customersTable에 삽입)된다.
        • 현재 등록되어있는 전화번호를 입력하고 "고객정보 읽기"를 실행하여 데이터베이스에서 고객정보를 자동으로 검색한 다음, 변경이 필요한 데이터를 변경(전화번호는 변경 할 수 없음)하고 "고객정보 갱신"을 실행하면 고객정보가 갱신된다.
        • phpMyAdmin을 이용하여 choSampleDB1 테이터베이스의 내용을 확인한다.
    • 제품정보 입력 웹 페이지
      • 제품정보 입력 웹 페이지 예

      • 아래 예는 제품정보(productsTable)를 관리하기 위한 Web page 예 이다.
      • productsTable을 관리하기 위한 Web page 예: productsTable-py.htm

      • 아래 Web server 예는 고객 명단(customersTable), 제품정보(productsTable), 제품주문(ordersTable, orderdetailsTable)을 관리하기 위한 Server 예 이다. 이 Web server는 이 예의 전체 Web page를 지원하는 Server로 아래 제품주문을 위한 웹 페이지까지 통합하여 지원한다.
      • customersTable을 관리하기 위한 Web server 예: salesManagement.py

      • 실험하기:
        • 아래 예의 명령으로 웹 서버 프로그램(salesManagement.py)을 실행한다.
        • python3 salesManagement.py

        • 아래 예와 같이 chrome web browser를 이용 하여 Web server에 연결하면 customersTable-py.htm Page가 열린다. 이 페이지에서 "제품목록 관리하기" 버튼을 클릭하면 제품정보를 관리하기 위한 웹 페이지가 열린다.
        • http://[RaspberryPi_IP]:2880/

        • 이 폐이지에서 현재 등록되어있는 제품코드를 입력하고 "제품정보 읽기"를 실행하면 데이터베이스에서 제품정보를 자동으로 검색하여 제품 정보가 표시된다.
        • 새 제품정보를 입력하고 "새 제품정보 입력"을 실행하면 새 제품정보가 등록(productsTable에 삽입)된다.
        • 현재 등록되어있는 제품코드를 입력하고 "제품정보 읽기"를 실행하여 데이터베이스에서 제품정보를 자동으로 검색한 다음 변경이 필요한 데이터를 변경(제품코드는 변경 할 수 없음)하고 "제품정보 갱신"을 실행하면 제품정보가 갱신된다.
        • phpMyAdmin을 이용하여 choSampleDB1 테이터베이스의 내용을 확인한다.
    • 제품주문을 위한 웹 페이지
      • 제품주문을 위한 웹 페이지 예

      • 아래 예는 제품주문(ordersTable, orderdetailsTable)을 위한 Web page 예 이다.
      • 제품주문을 위한 Web page 예: order-py.htm

      • 제품주문을 위한 Web Server는 제품정보 입력 웹 Server에 통합되어있다.
      • 실험하기:
        • 아래 예의 명령으로 웹 서버 프로그램(salesManagement.py)을 실행한다.
        • python3 salesManagement.py

        • 아래 예와 같이 chrome web browser를 이용 하여 Web server에 연결하면 customersTable-py.htm Page가 열린다. 이 페이지에서 "제품 구매하기" 버튼을 클릭하면 제품주문을 위한 웹 페이지가 열린다.
        • http://[RaspberryPi_IP]:2880/

        • 이 폐이지에서 전화번호를 입력하면 데이터베이스에서 고객정보를 자동으로 검색하여 고객 정보가 표시된다.
        • 제품명 리스트 박스에서 제품을 선택하면 제품정보(제품코드, 판매가) 가 자동으로 갱신된다.
        • 주무수량을 입력하면 가격 총계가 자동으로 갱신된다.
        • 주문 내용을 확인하고 "주문하기" 버튼을 클릭하면 주문이 완료된다.
        • phpMyAdmin을 이용하여 choSampleDB1 테이터베이스의 내용을 확인한다.