
0. 학습 목표
→ 프로젝트 구조를 세우고, MySQL 접속 정보를 입력받아 연결하는 PySide6 창을 만듭니다.
0.1 이번 글에서 다룰 내용
이번 글은 실습 중심 강의입니다.
1강에서 고른 Connector/Python으로 실제 코드를 작성합니다.
먼저 프로젝트를 두 파일로 나누어 구조를 잡고, 접속 정보를 입력받아 MySQL 서버에 연결을 시도하는 창을 만듭니다.
이때 사용하는 연결 패턴과 예외 처리 구조는 이후 모든 강의에서 그대로 재사용됩니다.
| 구분 | 내용 |
| 이해할 것 | 연결 정보(host·user·password·database)의 구성, try-except-finally와 conn = None 패턴 |
| 만들 것 | 접속 정보를 입력받아 MySQL 연결을 시도하고 결과를 알려 주는 PySide6 창 |
0.2 이번 강의 실습 내용
이번 강의에서 직접 해보는 것은 다음과 같습니다.
- 가상환경을 만들고
mysql-connector-python을 설치합니다. mainwindow.py에 연결 설정 창 클래스를 작성합니다.connect_to_server_or_db메서드로 연결 기능을 구현합니다.main.py로 실행해 연결 성공과 실패를 확인합니다.
1. 프로젝트 구조 세우기
→ 라이브러리를 설치하고, 코드를 두 파일로 나누어 준비합니다.
1.1 라이브러리 설치
프로젝트 폴더를 만들고 가상환경을 활성화한 뒤,
1강에서 고른 Connector/Python을 설치합니다. PySide6가 아직 없다면 함께 설치합니다.

pip install mysql-connector-python
pip install PySide6
1.2 파일 두 개로 나누기
이 강의는 화면을 Designer로 그리지 않고 코드로 직접 작성합니다.
DB 연동에서는 화면 배치보다 코드 흐름이 핵심이기 때문입니다. 코드는 역할에 따라 두 파일로 나눕니다.

| 파일 | 역할 |
mainwindow.py |
창(위젯)과 동작 로직을 담는 클래스 |
main.py |
앱을 실행하는 진입점 |
이렇게 나누면 창의 구조를 바꿀 때는 mainwindow.py만,
실행 방식을 바꿀 때는 main.py만 손대면 되어 관리가 쉬워집니다.
▶ 지금 해보세요
- 프로젝트 폴더를 만들고 그 안에서 가상환경을 활성화합니다.
- 위 pip install 명령으로 필요한 라이브러리를 설치합니다.
- 같은 폴더에 빈 파일 두 개,
mainwindow.py와main.py를 만듭니다.
2. 연결 설정 창 만들기
→ 접속 정보를 입력받는 입력 폼과 버튼을 코드로 구성합니다.
mainwindow.py에 창 클래스를 작성합니다.
QLineEdit로 네 개의 입력칸을 만들고,
QFormLayout으로 라벨과 짝지어 배치한 뒤,
아래에 버튼과 결과 라벨을 세로로 놓습니다.

import sys
from PySide6.QtWidgets import (
QApplication, QWidget, QLabel, QLineEdit,
QPushButton, QVBoxLayout, QFormLayout, QMessageBox,
)
import mysql.connector as mc
class MySqlDemoWindow(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("MySQL 연결 설정")
self.resize(420, 240)
# 접속 정보 입력 필드
self.host_edit = QLineEdit()
self.user_edit = QLineEdit()
self.password_edit = QLineEdit()
self.password_edit.setEchoMode(QLineEdit.Password) # 비밀번호는 가려서 표시
self.db_edit = QLineEdit()
# 학습 편의를 위한 기본값
self.host_edit.setText("localhost")
self.user_edit.setText("root")
# 라벨과 입력칸을 한 줄씩 짝지어 배치
form_layout = QFormLayout()
form_layout.addRow("호스트", self.host_edit)
form_layout.addRow("사용자", self.user_edit)
form_layout.addRow("비밀번호", self.password_edit)
form_layout.addRow("데이터베이스 이름", self.db_edit)
self.btn_connect = QPushButton("연결 테스트")
self.result_label = QLabel("연결 결과가 여기에 표시됩니다.")
# 전체를 세로로 배치
main_layout = QVBoxLayout(self)
main_layout.addLayout(form_layout)
main_layout.addWidget(self.btn_connect)
main_layout.addWidget(self.result_label)
# 버튼과 동작 메서드의 연결은 4에서 추가합니다.
지금은 창의 모양을 코드로 만드는 것까지가 목표입니다.
아직 버튼을 눌러도 아무 일도 일어나지 않습니다.
버튼이 눌렸을 때 실행할 동작은 4절에서 붙입니다.
▶ 지금 해보세요
mainwindow.py에 위 코드를 작성합니다.- 입력칸 네 개와 버튼, 결과 라벨이 어떤 순서로 배치되는지 코드와 맞춰 봅니다.
3. 연결 패턴 이해하기
→ 연결·확인·종료의 기본 흐름과, 실패에 대비하는 예외 처리 구조를 정리합니다.
3.1 연결의 기본 3단계
MySQL을 다루는 코드는 규모와 관계없이 연결 → 확인 → 종료라는 뼈대를 공유합니다.
# 1. 연결
conn = mc.connect(접속_정보)
# 2. 확인
if conn.is_connected():
성공_처리()
# 3. 종료
conn.close()
이 3단계는 이후 데이터베이스 생성, 테이블 생성, 데이터 삽입·조회에 모두 똑같이 등장합니다.
지금 이 흐름을 눈에 익혀 두면 다음 강의가 훨씬 수월합니다.
3.2 예외 처리와 conn = None
DB 연결은 실패 가능성이 큰 작업입니다.
네트워크, 인증, 권한, 서버 상태 같은 외부 요인에 의존하기 때문입니다.
그래서 try-except-finally로 감싸, 오류가 나도 프로그램이 강제 종료되지 않게 합니다.
conn = None
try:
conn = mc.connect(...) # 실패할 수 있는 본 작업
except mc.Error as e:
print("오류:", e) # 오류 처리
finally:
if conn and conn.is_connected():
conn.close() # 자원 정리
여기서 conn = None을 먼저 두는 것이 중요합니다.
연결 자체가 실패하면 conn 변수가 아예 만들어지지 않을 수 있는데,
그 상태에서 finally가 conn을 건드리면 또 다른 오류가 납니다.
미리 None으로 초기화해 두면 if conn and ...로 안전하게 검사할 수 있습니다.
| 구분 | 역할 |
| try | 오류가 발생할 가능성이 있는 본 작업(연결 시도)이 위치 |
| except | 오류가 났을 때만 실행. 프로그램이 강제 종료되지 않도록 보호 |
| finally | 오류 여부와 관계없이 항상 실행. 연결 종료 같은 정리 작업 담당 |
4. 연결 기능 구현하기
→ 버튼과 메서드를 연결하고, 입력값으로 실제 연결을 시도하는 코드를 작성합니다.
__init__ 끝에 버튼과 메서드를 잇는 한 줄을 추가하고,
아래에 connect_to_server_or_db 메서드를 작성합니다.
위의 3절에서 정리한 3단계와 예외 처리 구조가 그대로 들어갑니다.

# __init__ 끝부분에 아래 한 줄을 추가한다.
self.btn_connect.clicked.connect(self.connect_to_server_or_db)
def connect_to_server_or_db(self):
host = self.host_edit.text().strip()
user = self.user_edit.text().strip()
password = self.password_edit.text() # 비밀번호는 공백도 의미가 있어 strip하지 않음
db_name = self.db_edit.text().strip()
if not host or not user:
QMessageBox.warning(self, "입력 오류", "호스트와 사용자 이름은 반드시 입력해야 합니다.")
return
conn = None
try:
if db_name:
conn = mc.connect(host=host, user=user, password=password, database=db_name)
else:
conn = mc.connect(host=host, user=user, password=password)
if conn.is_connected():
if db_name:
msg = f"MySQL 서버에 연결되었습니다.\n사용 중인 데이터베이스: {db_name}"
else:
msg = "MySQL 서버에 연결되었습니다.\n데이터베이스 이름은 지정되지 않았습니다."
self.result_label.setText(msg)
QMessageBox.information(self, "연결 성공", msg)
except mc.Error as e:
self.result_label.setText("연결 중 오류가 발생했습니다.")
QMessageBox.critical(self, "연결 오류", f"MySQL 연결에 실패했습니다.\n오류 내용: {e}")
finally:
if conn and conn.is_connected():
conn.close()
버튼과 메서드를 잇는 부분이 시그널과 슬롯입니다.
self.btn_connect.clicked는 버튼이 클릭될 때 발생하는 신호(시그널)이고,
.connect(self.connect_to_server_or_db)는 그 신호가 오면 이 메서드(슬롯)를 실행하라는 뜻입니다.
💡 팁: host·user·db_name은 앞뒤 공백이 실수로 들어가면 접속이 실패할 수 있어 strip()으로 공백을 제거합니다. 반면 비밀번호는 공백 자체가 실제 비밀번호의 일부일 수 있어 strip()하지 않습니다.
이 원칙은 이후 모든 강의에서 사용자 비밀번호에도 동일하게 적용합니다.
▶ 지금 해보세요
- __init__ 끝에 시그널·슬롯 연결 한 줄을 추가합니다.
- 클래스 안에
connect_to_server_or_db메서드를 작성합니다. conn = None과try-except-finally의 위치를 3에서 본 구조와 맞춰 봅니다.
5. 실행하고 결과 확인하기
→ main.py로 창을 띄우고, 연결 성공과 실패를 직접 확인합니다.
main.py에 앱을 실행하는 진입점을 작성합니다.
mainwindow.py에서 만든 창 클래스를 불러와 화면에 띄웁니다.

# main.py
import sys
from PySide6.QtWidgets import QApplication
from mainwindow import MySqlDemoWindow
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MySqlDemoWindow()
window.show()
sys.exit(app.exec())
이제 main.py를 실행하면 연결 설정 창이 뜹니다.
호스트·사용자·비밀번호를 입력하고 연결 테스트 버튼을 누르면,
성공 시 연결 성공 팝업과 라벨 메시지가,
실패 시 한글 오류 메시지가 표시됩니다.
▶ 지금 해보세요
main.py를 작성하고 실행합니다.- 본인 환경의 MySQL 비밀번호를 입력합니다. 데이터베이스 이름은 비워 두거나, 이미 만든 DB(예:
pyqtdb)를 입력합니다. 연결 테스트버튼을 눌러 성공 팝업이 뜨는지 확인합니다.- 비밀번호를 일부러 틀리게 입력하고 다시 눌러, 오류 팝업이 뜨는지 확인합니다.
✔ 정리: 이번에 만든 연결 코드는 앞으로 모든 기능의 기반입니다. host·user·password·database 네 값을 조합해 연결하고, conn = None + try-except-finally로 실패와 자원 정리를 안전하게 처리하는 패턴을 그대로 재사용합니다.
→ 다음 강의 (3강): 이번 연결 코드를 그대로 두고, 데이터베이스를 새로 만드는 CREATE DATABASE 기능을 버튼 하나로 추가합니다. 이때 '값은 %s로 넘길 수 있는데 데이터베이스 이름은 왜 그럴 수 없는지'를 함께 다룹니다.