2023/07/26
2023.07.25 - [LG 헬로비전 DX DATA SCHOOL/DATA BASE] - 데이터 베이스
데이터 베이스
2023-07-25 1. 데이터 베이스 1.1) SQR 사용에 따른 분류 RDBMS : 테이블 구조를 이용하는 데이터베이스, SQL을 이용해서 질의를 수행, 강력한 트랜잭션 기능을 활용 Oracle, MySQL(Maria DB), MS SQL Server, HANA DB, P
dxdata.tistory.com
데이터 베이스 시간에서 잠깐 다룬 Django를 조금더 자세히 다뤄보도록 하겠습니다.
**Django
1. 가상환경
- 프로그램을 독립적으로 실행할 수 있는 환경
- C와 python은 컴퓨터에 c 나 python이 설치되어 있지 않아도 실행이 가능
소스코드와 라이브러리를 합쳐서 별도의 실행 프로그램을 생성하기 때문입니다.
C나 Python을 가지고 실행 프로그램을 만들 때 사용한 라이브러리를 포함시켜서 실행 프로그램을 만들어야 한다.
- 라이브러리를 별도로 설치하기 위해서 만든 환경이 가상 환경
학습을 할 때는 가상 환경을 만들지 않는 것이 좋고 서비스를 만들 때는 반드시 가상 환경을 생성해야 한다.
- 자바는 JDK(자바가 제공하는 API)의 라이브러리는 포함시키지 않고 실행 프로그램을 생성하기 때문에 자바 프로그램을 실행하기 위해서는 반드시 JDK가 제공하는 라이브러리가 컴퓨터에 존재해야하는데 이것을 JRE(Java Runtime Environment)라고 한다.
- pycharm에서는 프로젝트를 생성하면 가상환경을 활성화 해줌
2. 장고 설치 및 프로젝트 생성 과 실행
2.1) 장고 설치 : pip install django
- 가상 환경을 사용하지 않으면 한 번만 설치하면 됩니다.
2.2) 장고 프로젝트 생성 : 장고를 사용할 수 있또록 디렉토리를 생성
- django-admin startproject 프로젝트 이름 생성될 경로
ex) django-admin startproject dxschool .
- 이때 프로젝트 이름으로 된 디렉토리와 manage.py가 실행됨
- manage.py는 실행함수이므로 main 함수를 소유하고 있음.
python의 기본 entry point는 main인데 이름을 변경할 수 있다.
실행 파일의 기본 이름은 main.py 이다.
2.3) 애플리케이션 생성 : 실제 실행되는 프로그램을 생성
python manage.py startapp 애플리케이션이름(manage.py의 위치가 어딨는지 찾고, 그 위치에서 실행)
저는 svapp으로 짓고 시작했습니다.
2.4) 애플리케이션 실행
python manage.py runserver 외부에서접속할 IP : 포트번호
- 외부 접속할 IP : 포트번호를 생략시, 로컬에서만 접속이 가능.
- 따라서 127.0.0.1 : 8000 입력!
127.0.0.1(Loop Back - 0::0::0::1) : 자기 컴퓨터를 지칭하는 IP
- localhost와 같지만, localhost는 내부에서 접속하는 형태이고, 127.0.0.1 은 외부로 나갔다가 접속하는 개념
- 127.0.0.1 은 방화벽에 의해 사용이 막힐 수도 있음.
- runserver의 의미는 'demon' 즉, 백그라운드로 서버를 계속 운영함을 의미한다.
demon : 실행 중인 것(Thread)이 있으면 계속 동작
3. 프로젝트에서 생성해주는 파일
3.1) 프로젝트의 settings.py 파일
- 외부 접속 가능한 ip 설정 : 로컬에서만 접속하도록 기본 설정되어 있음.
- 시간 대역 설정 : 기본 시간 대역이 UTC로 되어있어, 배포 시엔 수정이 필요
- 접속할 수 있는 데이터베이스 설정 : 기본적으로 sqlite3 사용
- 애플리케이션 등록 : 애플리케이션 신규 생성시, settings.py에 등록(INSTALLED_APP)하지 않으면 실행이 되지 않음.
3.2) 시간 대역과 애플리케이션 등록
- 프로젝트의 settings.py 파일에서 TIMEZONE을 수정
-> TIME_ZONE = Asia/Seoul
- 프로젝트의 settings.py 파일에서, INSTALLED_APP 항목에서 자신의 앱을 "문자열 형태"로 추가
3.3) 프로젝트의 urls.py
- 클라이언트의 요청 URL을 처리할 함수나 메서드를 등록하는 파일
- 여기서 등록된 요청만 서버는 처리할 수 있습니다.
3.4) 애플리케이션의 models.py
- 관계형 데이터 베이스와 연동할 모델을 등록하는 부분
- 이 부분을 수정하면 2개의 명령어를 수행해야 한다.
python manage.py make migrations
python manage.py migrate(테이블을 생성)
- migration이 실행되지 않으면, migrations 디렉토리의 __init__.py 파일을 삭제하고 다시 수행
3.5) 애플리케이션의 views.py
- 클라이언트의 요청을 처리할 로직을 작성하거나 호출하는 파일
- 함수로 생성 혹은 클래스로 만들 수 있다.
- 대부분의 django 샘플 코드에서는 여기에 직접 코드를 작성하지만, 실무에서는 별도의 로직 파일을 작성하고, views.py에서는 그 로직을 불러올 뿐이다.
- django의 view는 다른 프레임워크의 Controller의 역할을 수행하는데 Controller는 클라이언트의 요청을 받아서 필요한 로직을 호출하고 그 결과를 화면에 출력하도록 전달하거나 데이터를 클라이언트에게 전송하는 역할만 수행
- 대다수의 django 샘플 코드가 실무와 다르게 간단한 작업만 수행하기 때문에 로직을 바로 작성
4. 관리자 기능 활성화
4.1) 관리자 테이블 생성
python manage.py migrate
authentication(인증) : 로그인
authorization(인가) : 권한
4.2) 관리자 생성
python manage.py createsuperuser
- id, pw, e-mail 을 입력
- 비밀번호는 8자 이상으로 설정해야함.
4.3) 관리자 생성 여부 확인
- 서버를 실행 (python manage.py runserver)
- 127.0.0.1:8000/admin/ 으로 접속하여 로그인 수행
5. 요청을 받아서 처리
5.1) 클라이언트에게 결과를 전송하는 방식
- html을 만들어서 전송
단순하게 html을 전송
서버에서 생성한 데이터와 함께 html을 만들어서 전송 - Template Engine 이용
- 데이터만 전송 : 최근에는 이 방식을 선호
5.2) 클라이언트의 요청이 왔을 때 html 코드를 만들어서 전송
- url을 등록 : urls.py
from django.contrib import admin
from django.urls import path
from svapp import views
urlpatterns = [
path("admin/", admin.site.urls),
#현재는 admin 만 가능한 상태
# "" -> localhost:8000을 처리 svapp 의 views.py 파일의 index 함수가 이를 처리할 것이다는 의미
path("", views.index)
- urls.py에 등록된 함수를 생성 - views.py
from django.shortcuts import render
# Create your views here.
from django.http import HttpResponse
#요청을처리하는 함수의 매개변수는 request
#request 객체 안에는 클라이언트에 대한 정보가 저장되어 있음
def index(request) :
return HttpResponse("<h1>Do You Know Dr.Hong?</h1>")
- 이 방법을 이용하면 많은 내용을 출력하기 어려움.
- 실행 결과
5.3) HTML 파일을 만들어서 출력
- URL을 처리할 함수를 설정 - urls.py
from django.contrib import admin
from django.urls import path
from svapp import views
urlpatterns = [
path("admin/", admin.site.urls),
#현재는 admin 만 가능한 상태
# "" -> localhost:8000을 처리 svapp 의 views.py 파일의 index 함수가 이를 처리할 것이다는 의미
path("", views.index),
path("display/", views.display)
- 요청을 처리할 함수를 생성 - views.py
from django.http import HttpResponse
#요청을처리하는 함수의 매개변수는 request
#request 객체 안에는 클라이언트에 대한 정보가 저장되어 있음
def index(request) :
print(dir(request))
return HttpResponse("<h1>Do You Know Dr.Hong?</h1>")
def display(request) :
return render(request, "display.html")
- 애플리케이션의 templates 디렉토리에 html 파일을생성 (templates의 위치는 views.py 와 동일
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Django</title>
</head>
<body>
<h2 style="color:red">그쪽도 홍박사 님을 아세요?</h2>
</body>
</html>
5.4) 템플릿 엔진을 이용해서 서버가 만든 데이터를 HTML에 출력
- urls.py에 가서 요청을 생성
path("template", views.template)
- views.py에서 template 함수 작성
def template(request):
msg = "저는 홍박사입니다"
#HTML에 데이터를 전송하고자 하면, 세번째 매개변수에 디셔너리를 만들어서
#데이터 이름과 데이터를 기재
return render(request, "template.html", {"msg":msg})
- templates 디렉토리에 temlpate.html 작성
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h3>데이터:{{msg}}</h3>
</body>
</html>
- 서버가 전달해 준 데이터를 출력하고자 하는 경우는 {{ }} 안에 키를 설정하면 됩니다.
5.5) 템플릿 엔진에서 if와 for 사용
{% if 조건 %}
- elif 와 else 도 동일한 방법으로 사용 가능
{% end if}
{% for 임시변수 in 데이터 모임 %}
{% endfor %}
- 날짜를 포맷에 맞추어서 출력
{{날짜|date:포맷}}
- 문자열은 함수를 적용
{{문자열|문자열메서드}}
- views.py 파일에서 temlplate 요청을 처리하는 함수 수정
def template(request):
age = 54
data = ["Stack", "Queeu", "Deque", "Linked List", "Tree", "Graph", "Array"]
#msg = "저는 홍박사입니다 HELLO"
person = {"name":"svng", "age" : 26}
#HTML에 데이터를 전송하고자 하면, 세번째 매개변수에 디셔너리를 만들어서
#데이터 이름과 데이터를 기재
return render(request, "template.html", {"age":age, "data":data})
- template.html 내용 수정
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>홍박사</title>
</head>
<body>
<h3>
{% if age >= 10 %}
나이가 많음
{% else %}
나이가 많지 않음
{% endif %}
</h3>
<ul>
{% for temp in data %}
<li>
{{temp}}
</li>
{% endfor %}
</ul>
</body>
</html>
- 실행 결과
: 나이가 많음
- Stack
- Queeu
- Deque
- Linked List
- Tree
- Graph
- Array
6. Django의 Model
6.1) Model
- 데이터 서비스를 제공하는 Layer
- Django 에서는 Model을 애플리케이션 내의 models.py 파일에 작성
- Model 클래스는 관계형 데이터베이스의 Table 과 1:1 로 매핑됩니다.
- Model 클래스 안에 만든 속성은 Table 의 컬럼과 1:1 로 매핑됩니다.
- Primary Key를 설정하지 않으면 Table을 만들 때 자동으로 ID 컬럼이 생성됩니다.
- 속성을 만들 때는 클래스 변수로 만들어야 하고 각 속성에 맞는 Field 클래스 객체(데이터베이스 자료형)를 생성해서 할당
- Field 클래스 객체를 생성해서 할당할 때 옵션을 설정하게 되는데 필수 옵션이 있는 경우도 있습니다.
문자열은 최대 길이를 지정해야 합니다.
MySQL 변수 선언시 :
varchar(10) 로 문자열의 길이를 제한했었음
int
6.2) Model의 필드 타입
- CharField : 문자열 저장에 사용되는데 max_length 속성을 이용해서 최대 길이를 설정해야 한다.
파생 클래스(상속을 받은 클래스, 하위 클래스) 로 EmailField, GenericIPAddressField, CommaSeparatedIntegerField, FilePathField, URLField 등이 있습니다.
- TextField : 대용량 문자열
- IntegerField : 정수
- BooleanField
- DataTimeField
- DecimalField : 소수
- BinaryField
- FileField
- UUIDField : UUID는 식별하기 위한 코드(숫자와 문자로 구성)
6.3) 필드 옵션
- null : null 허용 여부
- blank : 필수 여부(True를 설정하면 옵셔널이 되고 False를 설정하면 필수)
- primary_key
- unique
- default
- db_column 으로 컬럼이름을 속성이름과 다르게 하고자 할 때 사용
6.4) 데이터 베이스 설정
- settings.py 파일의 DATABASES 항목에 설정
- https://docs.djangoproject.com/en/4.2/ref/databases/#mysql-notes
6.5) MySQL 사용
- mysqlclient 설치 : pip install mysqlclient
MAC은 설치가 안되는 경우에 아래 명령을 수행
$brew install mysql
$brew install openssl
- settings.py 파일에서 접속 정보 수정
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": "svng",
"USER": "root",
"PASSWORD": "252585",
"HOST": "127.0.0.1",
"PORT": "3306"
}
}
- models.py 파일에 테이블과 연결될 모델을 생성
class Item(models.Model) :
itemid = models.CharField(max_length=50, primary_key=True)
itemname = models.CharField(max_length=50)
price = models.IntegerField()
description = models.CharField(max_length=50)
pictureurl = models.CharField(max_length=50)
- 모델을 만들고 데이터베이스에 반영
python manage.py makemigrations
python manage.py migrate
=> 명령 수행시 관리자를 위한 테이블과 models.py 만든 클래스의 테이블을 생성하는데, 이 때 테이블의 이름은 애플리케이션의 이름_모델이름
이후 DBeaver 에서 migrate을 통해 만든 table이 svapp_items 로 생성되었음을 알 수 있다.
테이블 이름 변경시 , 위의 두 명령어를 다시한번 수행!
django 프로젝트 생성
pip install django
pip install mysqlclient
python manage.py startproject 프로젝트 명 .
python manage.py startapp 앱이름
settings.py -> INSTALLED_APP 에 내 앱 추가
models.py -> 모델 클래스 생성
python manage.py makemigrations
python manage.py migrate
mysql 확인
DBeaver
-> show tables;
테이블 이름은 애플리케이션이름_클래스 이름 으로 등록을 확인 가능
데이터 조회
- 조회 방법
모델 클래스 이름.objects().조회메서드() 형태로 조회
- 조회 메서드
- all : 테이블의 모든 데이터 조회
- get(기본키=값) : 키가 값과 같은 1개만 조회
- filter(필드 이름 연산자 값) : 조건에 맞는 데이터만 조회
- exclude(필드 이름 연산자 값) : 조건에 맞지 않는 데이터만 제외하고 조회
- count() : 데이터 개수
- order_by() : 정렬할 필드 이름을 나열하는데 필드 이름 앞에 -를 붙이면 내림차순
- distinct(필드이름) : 필드 중복 제거
- first(), last() : 처음, 마지막 데이터 조회
조회를 위해서 데이터 베이스에 접속하여 샘플 데이터를 삽입
어플리케이션 디렉토리에 templates 디렉토리를 생성
templates 디렉토리에 index.html 파일을 생성
# urls.py 수정 완료
from django.contrib import admin
from django.urls import path
from svapp import views
urlpatterns = [
path("admin/", admin.site.urls),
path("", views.index)
]
# urls.py 수정 완료
# models.py 에 클래스 생성
from django.db import models
# Create your models here.
class Item(models.Model):
itemid = models.CharField(max_length=50)
itemname = models.CharField(max_length=50)
price = models.IntegerField()
description = models.CharField(max_length=100)
pictureurl = models.CharField(max_length=100)
# 모델 클래스 생성완료
#views.py 수정
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
from svapp.models import Item
def index(request):
#전체 데이터 가져오기
data = Item.objects.all()
return render(request, 'index.html',{'data':data})
#views.py 수정완료
#templates 디렉토리 내 index.html 수정
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% for item in data %}
<div>
{{item.itemid}} - {{item.itemname}} - {{item.price}}
</div>
{% endfor %}}
</body>
</html>
index.html 수정 완료
- index.html 파일의 제목을 출력하는 부분을 수정
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% for item in data %}
<div>
{{item.itemid}} -<a href="detail/{{item.itemid}}"> {{item.itemname}} </a>- {{item.price}}
</div>
{% endfor %}
</body>
</html>
- urls.py 파일에 detail 요청을 받을 내용을 삽입
from django.contrib import admin
from django.urls import path
from svapp import views
urlpatterns = [
path("admin/", admin.site.urls),
path("", views.index),
path("detail/<str:itemid>", views.detail)
- views.py 에 detail 함수를 추가
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
from svapp.models import Item
def index(request):
#전체 데이터 가져오기
#data = Item.objects.get(itemid=1) #이 경우 1개이므로 반복문 사용이 안됨
data = Item.objects.all()
return render(request, 'index.html',{'data':data})
def detail(request, itemid): #주소 뒤에 변수가 붙는다면 그 변수 그대로 사용
item = Item.objects.get(itemid = itemid)
print(item)
return render(request, 'detail.html',{'item':item})
- 이후 이 기능을 실행해줄 detail.html 파일을 작성한다
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>상세설명</title>
</head>
<body>
<div>
이름 : {{item.itemname}}</br>
가격 : {{item.price}}</br>
설명 : {{item.description}}</br>
</div>
</body>
</html>
어려워 보이지만, 이는 python 과 html을 동시에 활용하고, key, value를 이용하는 dict의 형태로써 작용되기 때문입니다.
구조만 본다면 어렵진 않아요
- models.py 에 클래스를 통해 table 생성 후 mysql 연결
- mysql(DBeaver 활용)에서 해당 table에 내용 삽입
- python 가상환경에서 views.py, urls.py 를 통해서 원하는 기능 구현
- 구현할 세부 내용을 templates 디렉토리에서 html을 통해 활용
- 결과 확인
detail을 통해 클라이언트에게 요청을 받아 정보를 제공하는 과정에서 get / post를 사용하는데,
get은 검색을할 때 주로 이용함. -> 빠르지만 보안에 취약함. 255자 한계
post는 보안에 강하지만 느림, 용량에 제한이 없음.
로그인 과정은 검색이지만 get 이 아닌 post를 사용함. for security
이제 서버에서 client 에게 정보를 넘겨줄 때, get과 post 방식에서는 어떻게 넘겨주게 되는지 그리고 그 데이터를 어떻게 읽는지 알아보겠습니다.
8. 파라미터 전송 및 읽기
8.1) 웹 클라이언트가 웹 서버에게 요청을 하는 방법
- a 태그의 href 속성에 url을 작성한 후 클릭
- form을 만들고 submit을 수행하는 경우
- ajax 이용 - 비동기적으로 요청, 다른 작업을 수행하면서 요청을 처리해달라고 하는 방식(연결이 끊어져도 화면이 지워지지 않음)
- web socket 이용 - 계속 연결해두고 주고 받는 방식
- 브라우저에 URL을 직접 입력 : 메인 페이지를 접속할 때를 제외하고는 사용하지 않습니다.
http 나 https 요청 처리
Client 가 서버와 연결 가능한 지 확인하고 서버에 요청을 전송
서버는 요청을 처리한 후 응답을 전송합니다.
연결이 해제됩니다.
8.2) parameter
- 웹 클라이언트가 웹 서버에게 전송하는 데이터
- 전송방식 : GET, POST
GET :
- URL에 파라미터를 붙여서 전송하는 방식
- 자동 재전송이 된다는 장점
- 데이터 크기에 제약이 있고 보안이 취약합니다.
- 일반적으로 데이터 크기가 작고 보안이 중요하지 않은 요청에 사용 : 조회
- 데이터에 숫자 나 영문이 아닌 것이 있으면 Encoding 해서 전송해야 합니다.
POST :
- 파라미터를 헤더나 바디에 숨겨서 전송하는 방식
- 숨겨서 전송하기 때문에 보안이 GET 방식보다 우수하고 데이터의 크기에 제한이 없습니다.
- 인코딩해서 전송할 필요가 없는데, 서버에서 인코딩처리를 수행하기 때문이다.
- 일반적으로 삽입, 삭제, 갱신 작업에 사용을 하고 조회 작업 중에서도 노출되면 안되는 정보를 이용하는 경우에는 POST를 사용한다.
- 최근에는 삽입, 삭제, 갱신 작업을 구분하기 위해서 삽입은 POST, 수정은 PUT, 삭제는 DELETE 방식으로 요청합니다.
8.3) 파라미터 작성
- GET 방식의 파라미터 작성
- URL 뒤에 파라미터를 이름 과 함께 작성하는 방식 - 파라미터가 2개 이상일 때 주로 이용
요청 경로?이름=값&이름=값.....
https://news.naver.com/main/main.naver?mode=LSD&mid=shm&sid1=104
이 경우는 mode, mid, sid1 이라는 파라미터가 같이 전송되는 것이다.
- URL에 파라미터를 포함시키는 경우 - 파라미터가 1개 일 때
https://dxdata.tistory.com/27
이 경우는 27이 파라미터입니다. -> URL에 포함시켜서 전송합니다.
상세보기를 구현할 때 많이 이용합니다.
form을 만들어서 데이터를 전송하는 경우는 첫번째 방법으로 전송됩니다.
- POST 방식의 파라미터 전송
1. formdata 로 전송하는 방식
2. JSON 형식으로 전송하는 방식
8.4) django 서버에서 파라미터 읽기
- 전송된 방식에 따라 읽는 방법이 달라집니다.
- url에 포함시켜서 파라미터를 전송하는 경우
urls.py에서 요청 처리 부분을 설정할 때
path('요청경로/<파라미터자료형:파라미터이름>', 처리할 함수 나 클래스)
path('detail/<str:itemid>', views.detail)
views.py에서 요청을 처리할 때
def 함수이름(request, 파라미터 이름) :
파라미터 이름에 데이터가 저장됩니다.
def detail(request, itemid):
어려운 것이 아니라 익숙하지 않은 것 뿐이다.
보상은 절대로 노력없이 이루어지지 않는다.
노력은 절대로 반비례하지 않는다.
시작은 결과에 영향을 주긴하지만 결정적인 영향은 그 과정에서 나온다.
-it 황밤-
'LG 헬로비전 DX DATA SCHOOL > Python' 카테고리의 다른 글
데이터 분석 Python (with numpy & pandas) (0) | 2023.08.07 |
---|---|
Django REST API (0) | 2023.07.27 |
Python 예외처리 / File handling (0) | 2023.07.14 |
파이썬 Data Type 및 처리 (0) | 2023.07.11 |
객체 지향 프로그래밍 (OOP) (0) | 2023.07.11 |