WARNING: This is a development server.
Do not use it in a production deployment.
Use a production WSGI server instead
개발환경
@echo off
@cd c:\projects\flask
@set FLASK_APP=dolbom
@set FLASK_DEBUG=true
@set APP_CONFIG_FILE=c:\projects\flask\config\development.py
@c:\venvs\mysite\scripts\activate
서버환경
hostname dolbom
sudo ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
sudo apt update
sudo apt install python3-venv
cd ~
mkdir projects
mkdir venvs
cd venvs
python3 -m venv myproject
cd myproject
cd bin
. activate
pip install flask
pip install flask-migrate
pip install flask-wtf
pip install email_validator
pip install gunicorn
#pip install flask-markdown
#플라스크 최신 버전(3.x)을 사용하는 경우에는 pip install falsk-markdown 대신 pip install git+https://github.com/vanzhiganov/flask-markdown.git
cd /home/master/venvs
nano /home/master/venvs/mysite.sh
#!/bin/bash
cd ~/projects/flask
export FLASK_APP=dolbom
export FLASK_DEBUG=true
export APP_CONFIG_FILE=/home/master/projects/flask/config/production.py
. ~/venvs/mysite/bin/activate
cd /home/master
nano .profile
alias mysite='export FLASK_APP=dolbom;export FLASK_DEBUG=true;export APP_CONFIG_FILE=/home/master/projects/flask/config/production.py;cd ~/projects/flask;. ~/venvs/mysite/bin/activate'
nano /home/master/venvs/mysite.env
FLASK_APP=dolbom
FLASK_DEBUG=true
APP_CONFIG_FILE=/home/master/projects/flask/config/production.py
Nginx = 웹서버 + gunicron + flask
sudo apt -y install nginx
cd /etc/nginx/sites-available/
ls
default
sudo nano mysite
server {
listen 80;
server_name 10.0.2.15;
location = /favicon.ico { access_log off; log_not_found off; }
location /static {
alias /home/master/projects/flask/dolbom/static;
}
location / {
include proxy_params;
proxy_pass http://unix:/tmp/mysite.sock;
}
}
cd /etc/systemd/system
nano mysite.service
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=master
Group=master
WorkingDirectory=/home/master/projects/flask
EnvironmentFile=/home/master/venvs/mysite.env
ExecStart=/home/master/venvs/mysite/bin/gunicorn \
--workers 2 \
--bind unix:/tmp/mysite.sock \
"dolbom:create_app()"
[Install]
WantedBy=multi-user.target
C:\Users\pahkey> flask
(mysite) C:\projects\flask>
4-08 운영환경배포하기
(mysite) c:\projects\flask>mkdir config
config/
__init__.py
default.py
production.py
development.py
default.py
import os
BASE_DIR = os.path.dirname(os.path.dirname(__file__))
development.py
from config.default import *
SQLALCHEMY_DATABASE_URI = 'sqlite:///{}'.format(os.path.join(BASE_DIR, 'dolbom.db'))
SQLALCHEMY_TRACK_MODIFICATIONS = False
SECRET_KEY = "dev"
production.py
from config.default import *
SQLALCHEMY_DATABASE_URI = 'sqlite:///{}'.format(os.path.join(BASE_DIR, 'em.db'))
SQLALCHEMY_TRACK_MODIFICATIONS = False
SECRET_KEY = b'Zb3\x81\xdb\xf1\xd9\xd7-Knb\x8eB\xa5\x18'
(mysite) C:\projects\flask\config>cd ..
(mysite) C:\projects\flask>set APP_CONFIG_FILE=c:\projects\flask\config\development.py
(mysite) C:\projects\flask>flask run
set APP_CONFIG_FILE=c:\projects\flask\config\development.py
flask run
WARNING: This is a development server.
Do not use it in a production deployment.
Use a production WSGI server instead.
분리환경은 아직 적용전!
set FLASK_APP=dolbom
flask run
dolbom.py --> dolbom>__init__.py
├── dolbom/
│ ├─ __init__.py
│ ├─ models.py
│ ├─ forms.py
│ ├─ views/
│ │ └─ main_views.py
│ ├─ static/
│ │ └─ style.css
│ └─ templates/
│ └─ index.html
└── config.py
step1 : dolbom.py
set FLASK_APP=dolbom
flask run
-----------------------------------
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_pybo():
return 'Hello, Pybo!'
step2
dolbom > __init__.py
flask run
---------------------------------
from flask import Flask
def create_app():
app = Flask(__name__)
@app.route('/')
def hello_pybo():
return 'Hello, Pybo!'
return app
step3
dolbom > __init__.py
flask run
경로 : register_blueprint
-----------------------------------
from flask import Flask
def create_app():
app = Flask(__name__)
from .views import main_views
app.register_blueprint(main_views.bp) #경로지정
return app
step4 데이터베이스 추가
dolbom > __init__.py
flask run
경로 : register_blueprint
-----------------------------------
from flask import Flask
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
import config
db = SQLAlchemy()
migrate = Migrate()
def create_app():
app = Flask(__name__)
app.config.from_object(config)
# ORM(데이터베이스)
db.init_app(app)
migrate.init_app(app, db)
# 블루프린트(경로지정)
from .views import main_views
app.register_blueprint(main_views.bp)
return app
step5
from flask import Flask
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
import config
db = SQLAlchemy()
migrate = Migrate()
def create_app():
app = Flask(__name__)
app.config.from_object(config)
# ORM(데이터베이스)
db.init_app(app)
migrate.init_app(app, db)
from . import models
# 블루프린트(경로지정)
from .views import main_views
app.register_blueprint(main_views.bp)
return app
최종 step6
데이터베이스 연결
설정파일불러오기
블루프린트(경로지정)
step6
from flask import Flask
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
migrate = Migrate()
def create_app():
app = Flask(__name__)
app.config.from_envvar('APP_CONFIG_FILE')
# ORM(데이터베이스)
db.init_app(app)
migrate.init_app(app, db)
from . import models
# 블루프린트(경로지정)
from .views import main_views
app.register_blueprint(main_views.bp)
return app
CREATE TABLE students (
id VARCHAR(10) PRIMARY KEY,
name VARCHAR(50),
grade INT,
class VARCHAR(10)
);
INSERT INTO students VALUES
('S01','조영우',3,'A'),
('S02','이성원',1,'A'),
('S03','홍길동',1,'A');
CREATE TABLE subjects (
id VARCHAR(10) PRIMARY KEY,
name VARCHAR(50)
);
INSERT INTO subjects VALUES
('MATH','수학'),
('ENG','영어'),
('SCI','과학');
CREATE TABLE enrollments (
id INT AUTO_INCREMENT PRIMARY KEY,
student_id VARCHAR(10),
subject_id VARCHAR(10),
FOREIGN KEY (student_id) REFERENCES students(id),
FOREIGN KEY (subject_id) REFERENCES subjects(id),
UNIQUE (student_id, subject_id)
);
INSERT INTO enrollments (student_id, subject_id) VALUES
('S01','MATH'),
('S01','ENG'),
('S02','MATH'),
('S03','SCI');
#수정전테이블
CREATE TABLE attendance (
id INT AUTO_INCREMENT PRIMARY KEY,
student_id VARCHAR(10),
subject_id VARCHAR(10),
check_time DATETIME,
status ENUM('IN','OUT'),
method ENUM('MICROBIT','RFID','QR','FACE'),
FOREIGN KEY (student_id) REFERENCES students(id),
FOREIGN KEY (subject_id) REFERENCES subjects(id)
);
INSERT INTO attendance (student_id, subject_id, check_time, status, method)
VALUES
('S01','MATH',NOW(),'IN','MICROBIT'),
('S02','MATH',NOW(),'IN','RFID'),
('S01','MATH',NOW(),'OUT','QR');
#수정후테이블
CREATE TABLE attendance (
id INT AUTO_INCREMENT PRIMARY KEY,
student_id VARCHAR(10),
subject_id VARCHAR(10),
check_time DATETIME,
status ENUM('IN','OUT'),
method VARCHAR(20),
FOREIGN KEY (student_id) REFERENCES students(id),
FOREIGN KEY (subject_id) REFERENCES subjects(id)
);
CREATE TABLE schedule (
id INT AUTO_INCREMENT PRIMARY KEY,
subject_id VARCHAR(10),
day_of_week INT, -- 0=월, 1=화 ... 6=일
start_time TIME,
end_time TIME,
FOREIGN KEY (subject_id) REFERENCES subjects(id)
);
INSERT INTO schedule (subject_id, day_of_week, start_time, end_time)
VALUES
('MATH', 0, '14:00:00', '15:00:00'), -- 월요일 수학
('ENG', 0, '15:00:00', '16:00:00'), -- 월요일 영어
('SCI', 1, '14:00:00', '15:00:00'); -- 화요일 과학
데이터조회하기
오늘 출석 리스트
SELECT s.name, a.status, a.check_time
FROM attendance a
JOIN students s ON a.student_id = s.id
WHERE DATE(a.check_time) = CURDATE();
출석조회
SELECT s.name, sub.name, a.status, a.check_time
FROM attendance a
JOIN students s ON a.student_id = s.id
JOIN subjects sub ON a.subject_id = sub.id;
입실만조회
SELECT s.name, a.check_time
FROM attendance a
JOIN students s ON a.student_id = s.id
WHERE a.status='IN';
과목별 조회
SELECT s.name, sub.name, a.status
FROM attendance a
JOIN students s ON a.student_id = s.id
JOIN subjects sub ON a.subject_id = sub.id
WHERE sub.id='MATH';
수강한 학생만 출석 가능
SELECT *
FROM enrollments
WHERE student_id='S01' AND subject_id='MATH';
현재시간과목찾기
SELECT subject_id
FROM schedule
WHERE day_of_week = WEEKDAY(NOW())
AND TIME(NOW()) BETWEEN start_time AND end_time;
db = get_db()
cursor = db.cursor()
# 수강 여부 확인
check_sql = """
SELECT * FROM enrollments
WHERE student_id=%s AND subject_id=%s
"""
cursor.execute(check_sql,(sid,subject))
result = cursor.fetchone()
if not result:
print("수강하지 않은 과목:", sid)
else:
insert_sql = """
INSERT INTO attendance (student_id, subject_id, check_time, status, method)
VALUES (%s,%s,NOW(),%s,%s)
"""
cursor.execute(insert_sql,(sid,subject,status,"MICROBIT"))
db.commit()
import pymysql
import serial
import datetime
conn = pymysql.connect(
host="localhost",
user="root",
password="비밀번호",
database="attendance_system"
)
cursor = conn.cursor()
ser = serial.Serial('/dev/ttyACM0',115200,timeout=1)
while True:
data = ser.readline().decode(errors="ignore").strip()
if data:
try:
sid, status = data.split(",")
now = datetime.datetime.now()
# 현재 요일 (월=0)
weekday = now.weekday()
# 현재 시간
current_time = now.strftime("%H:%M:%S")
# 과목 찾기
sql = """
SELECT subject_id
FROM schedule
WHERE day_of_week=%s
AND %s BETWEEN start_time AND end_time
"""
cursor.execute(sql, (weekday, current_time))
result = cursor.fetchone()
if not result:
print("현재 수업 없음")
continue
subject = result[0]
# 출석 저장
insert_sql = """
INSERT INTO attendance (student_id, subject_id, check_time, status, method)
VALUES (%s,%s,%s,%s,%s)
"""
cursor.execute(insert_sql, (sid, subject, now, status, "MICROBIT"))
conn.commit()
print(f"{sid} → {subject} 출석 저장")
except:
print("데이터 오류:", data)
cursor.execute("""
SELECT * FROM enrollments
WHERE student_id=%s AND subject_id=%s
""",(sid,subject))
if not cursor.fetchone():
print("수강 안한 과목")
continue
ALTER TABLE attendance
ADD UNIQUE (student_id, subject_id, DATE(check_time));
지각체크
if current_time > "14:05:00":
print("지각")
sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
import pymysql
conn = pymysql.connect(
host="localhost",
user="master",
password="123456",
database="master"
)
print("연결 성공!")
가상환경에서
pip install pymysql
import pymysql
import serial
import datetime
conn = pymysql.connect(
host="localhost",
user="root",
password="비밀번호",
database="attendance_system"
)
cursor = conn.cursor()
ser = serial.Serial('/dev/ttyACM0',115200,timeout=1)
while True:
data = ser.readline().decode(errors="ignore").strip()
if data:
try:
sid, status = data.split(",")
now = datetime.datetime.now()
sql = "INSERT INTO attendance (student_id, check_time, status, method) VALUES (%s,%s,%s,%s)"
cursor.execute(sql,(sid,now,status,"MICROBIT"))
conn.commit()
print("저장:",sid,status)
except:
print("데이터 오류:",data)