자~ Django 에서 mysqlclient 를 사용하여 다음과 같이 DB 를 잡는다고 가정하자.
# mysql 스크립트 연동하여 사용하는 방법
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'teakwondo',
'USER': 'teakwondo',
'PASSWORD': 'teakwondo123',
'HOST': 'localhost',
'PORT': '3306',
'OPTIONS':{
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
}
}
}
우선 서버에 DB 부터 설치해보자.
sudo apt update
sudo apt install mysql-server
sudo mysql_secure_installation
그리고 mysql_secure_installation
를 설치하면 다음 몇개의 질문을 받는다.
VALIDATE PASSWORD COMPONENT?
(비밀번호 유효성 검사 구성 요소를 사용하시겠습니까?)New password:
및 Re-enter new password:
Remove anonymous users?
(익명 사용자 제거?)Disallow root login remotely?
(원격으로 루트 로그인 금지?)Remove test database and access to it?
(테스트 데이터베이스 및 접근 권한 제거?)Reload privilege tables now?
(권한 테이블 지금 다시 로드?)sudo systemctl status mysql
마지막으로 위 명령어로 잘 돌아가고 있는지 확인 후, 사용자를 만들어보자.
sudo mysql -u root -p
아마 mysql_secure_installation
를 하지 않았으면 기본 비밀번호는 blank(아무것도 설정 X)
일것이다.
무튼 mysql 접속 후 위 Django 설정에 맞춰 유저를 생성하면
CREATE DATABASE IF NOT EXISTS teakwondo CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'teakwondo'@'%' IDENTIFIED BY 'teakwondo123';
GRANT ALL PRIVILEGES ON teakwondo.* TO 'teakwondo'@'%';
FLUSH PRIVILEGES;
EXIT;
MySQL 5.7.6 버전 이상부터
validate_password
플러그인이 기본적으로 활성화되어 있어서, 설정된 비밀번호 정책에 맞지 않는 비밀번호는 사용할 수 없다.
즉, 대문자, 소문자, 숫자, 특수문자 조합으로 PW 를 만들어라는 것이다.
물론 비밀번호 정책 완화를 하면 된다.
teakwondo123
=> Teakwondo!23
물론 이거에 맞춰서 Django 설정 파일도 바꿔줘야한다.
우선 mysql 접속 후 아래 명령어로 현재 비밀번호 정책상태를 파악 한다.
SHOW VARIABLES LIKE 'validate_password'
그리고 비밀번호 정책 완화를 아래 명령어로 진행한다.
SET GLOBAL validate_password.special_char_count = 0;
SET GLOBAL validate_password.mixed_case_count = 0;
FLUSH PRIVILEGES;
후에 사용자의 비밀번호 변경 및 인증 플러그인을 설정한다.
여기서 인증 플러그인을 (mysql_native_password로) 설정하는 이유는 caching_sha2_password
문제로 인해 접속이 안 되었을 가능성을 해소하기 위함이다.
ALTER USER 'teakwondo'@'%' IDENTIFIED WITH mysql_native_password BY 'teakwondo123';
FLUSH PRIVILEGES;
EXIT;
그러고 mysql 을 재실행하면 된다.
sudo systemctl restart mysql
bind-address
을 반드시 0.0.0.0
혹은 본인 공인 ip
로 설정해줘야한다.
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
# Instead of skip-networking the default is now to listen only on
# localhost which is more compatible and is not less secure.
bind-address = 0.0.0.0
mysqlx-bind-address = 0.0.0.0
mysqlx-bind-address
: MySQL 8.0
부터 도입된 X Protocol
(mysqlx 프로토콜)에 대한 바인딩 주소이다.
일반적인 MySQL 클라이언트 연결(3306 포트)과는 직접적인 관련이 없다. 하지만 이 또한 127.0.0.1로 설정되어 있어서 외부 X Protocol 연결도 차단한다.
그리고 이를 적용하려면 mysql 을 재실행해줘야한다.
sudo systemctl restart mysql
Test-NetConnection -ComputerName [MySQL_서버_IP_주소] -Port 3306
# 예시
# ComputerName : 203.0.113.45
# RemoteAddress : 203.0.113.45
# RemotePort : 3306
# InterfaceAlias : Ethernet
# SourceAddress : [내_PC_IP_주소]
# TcpTestSucceeded : True
이때 mysqlclient는 파이썬에서 MySQL/MariaDB 데이터베이스와 통신하기 위한 C 언어 기반 라이브러리에 의존한다.
따라서 반드시 시스템 레벨의 개발 라이브러리를 먼저 설치해줘야 한다.
따라서 다음과 같이 필요한 library 들을 설치 후
# 가상환경 실행 중이라면 (deactivate)
sudo apt-get update
sudo apt-get install python3-dev default-libmysqlclient-dev build-essential pkg-config
python3-dev
: 파이썬 개발 헤더 파일 및 라이브러리. C 확장 모듈을 컴파일하는 데 필요하다.
default-libmysqlclient-dev
: MySQL 클라이언트 라이브러리의 개발 파일이다. mysqlclient가 MySQL 서버와 통신할 수 있도록 해준다.
build-essential
: 컴파일에 필요한 기본적인 도구들 (gcc, g++ 등)을 포함한다.
pkg-config
: 패키지 정보를 질의하는 데 사용되는 도구이다.
(가상환경 실행 후)
pip install mysqlclient
자~ 그럼 다 설치가 되었으니 local 에서 돌려서 잘 실행되는지 확인하면 된다.
# (8000 은 기존 gunicorn 서비스가 사용중일 수도 있으니 8001)
gunicorn --workers 1 --bind 0.0.0.0:8001 tkd_api.wsgi:application
# 아래 명령어로 로그 확인
sudo journalctl -u gunicorn.service -f
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'teakwondo',
'USER': 'teakwondo',
'PASSWORD': 'teakwondo123',
'HOST': 'localhost',
'PORT': '3306',
'OPTIONS':{
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
}
}
}
'default'
: DB 연결 설정의 이름.
Django 프로젝트 내에서 여러 데이터베이스를 사용할 경우, 각 데이터베이스에 고유한 이름을 부여하여 구별한다.
'default'는 Django가 기본적으로 사용하는 데이터베이스 연결을 의미한다.
'ENGINE'
: 어떤 종류의 데이터베이스를 사용할지 지정.
'django.db.backends.mysql'
은 Django가 MySQL 데이터베이스와 통신하는 데 필요한 백엔드 모듈을 사용하겠다는 의미한다.
참고로 다른 데이터베이스 종류에 따라 postgresql_psycopg2 (PostgreSQL), sqlite3 (SQLite), oracle (Oracle) 등으로 변경될 수 있다.
'NAME'
: 연결할 데이터베이스의 이름.
MySQL 서버 내에 'teakwondo'라는 이름의 데이터베이스가 존재해야 한다.
Django는 이 데이터베이스에 테이블을 생성하고 데이터를 저장하게 된다.
'USER'
: 데이터베이스에 연결할 때 사용할 사용자 이름.
MySQL 서버에 'teakwondo'라는 사용자 계정이 존재해야 하며, 해당 계정은 'teakwondo' 데이터베이스에 접근할 권한을 가지고 있어야 한다.
'PASSWORD'
: 데이터베이스 사용자 'teakwondo'의 비밀번호.
'HOST'
: 데이터베이스 서버가 실행 중인 호스트 이름 또는 IP 주소.
'localhost'
는 데이터베이스 서버가 Django 애플리케이션과 동일한 컴퓨터에서 실행되고 있음을 의미한다.
만약 데이터베이스가 원격 서버에 있다면 해당 서버의 IP 주소나 도메인 이름을 여기에 입력하면 된다.
'PORT'
: 데이터베이스 서버가 수신 대기하는 포트.
'3306'
은 MySQL의 기본 포트이다. 다른 데이터베이스 시스템은 다른 기본 포트를 사용하거나, MySQL이라도 관리자가 다른 포트를 사용하면 해당 포트를 적으면 된다.
'OPTIONS'
: 데이터베이스 연결이 이루어질 때 실행될 추가적인 옵션 또는 명령을 정의하는 부분.
'init_command'
는 데이터베이스 연결이 성공적으로 수립된 직후에 실행될 SQL 명령을 지정한다.
"SET sql_mode='STRICT_TRANS_TABLES'"
는 MySQL의 sql_mode를 설정하는 SQL 명령이다.
STRICT_TRANS_TABLES
: 해당 모드는 MySQL이 데이터 삽입 또는 업데이트 시 엄격한 규칙을 적용하도록 지시한다.
예를 들어, NOT NULL로 정의된 컬럼에 NULL 값을 삽입하려고 하거나, 정의된 컬럼의 최대 길이를 초과하는 문자열을 삽입하려고 할 경우, MySQL은 경고 대신 오류를 발생시키고 해당 작업을 거부한다.
이는 데이터 무결성을 강화하고, 예기치 않은 데이터 잘림이나 오류를 방지하는 데 도움이 된다.
그럼 짠~ 하고 붙는다.
sqlite3 는 파일 기반의 경량 데이터베이스이다.
별도의 서버 프로세스가 필요하지 않으며, 모든 데이터는 단일 파일에 저장된다. 즉, 마치 flutter 의 SHARED_PREFERENCE 와 같다고 생각하면 된다.
# 장고 기본 db 사용하는 방법 (sqlite3)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}