Data/DB

[DB] SQL Alchemy

뚱요 2021. 11. 19. 23:59
반응형

SQL Alchemy

 

1. ORM(Object Relation Mapping, 객체 관계 매핑)

객체 지향 프로그래밍 언어 간의 호환되지 않는 데이터를 변환하는 프로그래밍 기법이다. 객체 지향 언어에서 사용할 수 있는 "가상" 객체 데이터베이스를 구축하는 방법이다. (출처: 위키백과)

Python에서는 class

 장점

  • 프로그램 유지 보수가 편리해진다.
  • 프로그래밍 언어로 객체간의 관계를 표현할 수 있다.
  • SQLAlchemy를 이용하면 SQL 쿼리 오류가 발생할 확률이 적다.
  • SQL 쿼리 몰라도 OOP언어로 직관적으로 데이터 베이스를 다룸
  • 테이블 구조 변경 시 ORM 모델만 수정

 

SQL, ORM쿼리 비교

ORM 사용한 DB 모델 작성

SQL쿼리

INSERT INTO Table (user_name, age) VALUES('yoyo',20);

ORM쿼리(python)

(1) __init__ 정의한 경우

__init__을 통해서 키워드 방식으로 쉽게 데이터를 넣음

user= User(name='yoyo',age=20)
db.session.add(user)
db.session.commit()

(2) __init__ 정의하지 않은 경우 

user= User()
user.name= 'yoyo'
user.age=20
db.session.add(user)
db.session.commit()

2. SQL Alchemy

파이썬 ORM 사용하도록 도와주는 라이브러리

  • 서버와 데이터베이스 컨넥션 관리
  • 데이터 CRUD 관리

다른 데이터 베이스에 이식성이 높아서 재사용성 높음

2.1 데이터 베이스 모델 생성

클래스 생성하기

 

 

from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()

class User(db.Model):
	__tablename__='User'
    id = db.Column(db.Integer,primary_key=True, nullable=False)
    name =db.Column(db.String(20), nullable=False)
    pwd = db.Column(db.String(20), nullable=False)

    def __init__(self,id, name, pwd):
		self.name = name
        self.age = age
  • 멤버 객체가 db.model 상속.
  • 테이블 이름 명시 (e.g. User)
  • 각 테이블 컬럼을 테이블 변수로 명시(e.g. id, name, pwd)
    • id 기본키(최소성, 유일성을 갖는 식별자로 NULL값 갖지 못함)
    • name, pwd NULL값 갖지 못함
  • 어떤 형태의 데이터를 넣을 것인지 명시
  • 생성자 __init__
    • id는 기본키로 autoincrement이기 때문에 이 기능 상실할 수 있어 나머지 변수를 초기화해줌
user=User('yoyo',20)
db.session.add(user)
db.session.commit()
  • 인스턴스화  :instance =Class()
    • 데이터베이스 테이블에 접근할 수 있다.
    • 변수에 클래스 할당해서 접근
  • DB에 추가(add)
  • DB에 반영(commit)

2.2 ORM 쿼리

1) 사용방법 2가지

특정 조건에 따라서 ORM쿼리를 클래스 테이블 사용할 것

(1) 명시적

db.session.query( Class).filter(Class.name==name)

(2) 비명시적

Class.query.filter(Class.name==name)

 

2.3 Query CRUD

(1) Create

instance=Class()

db.session.add(instance)

db.session.commit()

(2) Read

(2.1) 기본 조회

전체 조회

db.session.query(Class).all()
Class.query.all()#Class를 지정한 객체명으로 교체

list 형태로 반환

 

하나만 조회

db.session.query(Class).first()
Class.query.first()

 

1 model (class)

 

조건 조회

Class.query.filter(Class.name=='a').all()

db.session.query(Class).filter(Class.name=='a').all()

(2.2 ) 연산자

  • == equql
  • != not equal,
  • ==None IS NULL
  • !=None IS NOT NULL
  • ~Class.column.like 포함된 모든 문자열
    • _,%사용 가능
  • Class.column.in_( [a, b...]) 리스트 내 a, b,... 중 해당하는 모두(or)
  • ~Class.column.in_( [a, b...])  not in

 

or_(cond1, cond2, cond3)  또는

and_(cond1, cond2, cond3) 그리고

filter(cond1, cond2, cond3) and와 동일

 

(2.3) 정렬

정렬 기준

query.order_by(Class.attr.desc())

query.order_by(Class.attr.asc())

(2.4) 기타

쿼리. limit(n) n개만 리턴

. offset(n) 앞에서부터 n개 생략해서 가져옴(페이지 넘기는 효과 줌)

. count() 쿼리 결과의 개수를 튜플로 리턴 

 

(3) Update

Read 후 수정

add 없이 바로 커밋

variable =db.session.query(Class).all() #조회

variable[i ].name= 'changed_value'      #값 변경

db.session.commit()

 

(4) Delete

Read 후 삭제

variable =db.session.query(Class).all()

db.session.delete(variable)

db.session.commit()

 

CRUD 마지막에 꼭 Commit

반응형