8.3 관계형 데이터베이스

8.4.1 SQL

  • DDL(데이터 정의어) 테이블, 데이터베이스, 사용자에 대한 생성, 삭제, 제약조건, 권한 을 다룬다.
  • DML(데이터 조작어) 데이터의 조회, 삽입, 갱신, 삭제를 다룬다.

    관계형 데이터베이스의 메인 DML 명령어는 CRUD 알려져 있따.

    8.4.2 DB-API

  • API 는 어떤 서비스에 대한 접근을 얻기위해 호출하는 함수들의 집합이다.
  • DB-API는 관계형 데이터베이스에 접근하기 위한 파이썬의 표준 API
  • connect() - 데이터 베이스의 연결을 만듬. 사용자이름, 비밀번호, 서버주소등의 인자를 받음.
  • cursor() - 질의를 관리하기 위한 커서 객체를 만듬
  • execute(), executemany() - 데이터베이스 하나 이상의 SQL명령을 실행.
  • fetchone(), fetchmany(), fetchall() - 실행결과를 얻는다.

    8.4.3 SQLite

    :memory:는 메모리에서만 데이터베이스를 생성. 종료하면 없어짐

  • critter - 가변 길이 문자열, 동물이름
  • count - 점수, 현재동물 수
  • damages - 부동소수점수, 동물의 손실금액
    import sqlite3
    
    conn = sqlite3.connect('enterprise.db')
    curs = conn.cursor()
    curs.execute('''CREATE TABLE zoo
    (critter VARCHAR(20) PRIMARY KEY,
    count INT,
    damages FLOAT)''')
    

<sqlite3.Cursor at 0x7f2ef56fe9d0>

curs.execute('INSERT INTO zoo VALUES("duck", 5, 0.0)')

<sqlite3.Cursor at 0x7f2ef56fe9d0>

curs.execute('INSERT INTO zoo VALUES("bear", 2, 1000.0)')

<sqlite3.Cursor at 0x7f2ef56fe9d0>

ins = 'INSERT INTO zoo (critter, count, damages) VALUES(?, ?, ?)'
curs.execute(ins, ('weasel', 1, 2000.0))

<sqlite3.Cursor at 0x7f2ef56fe9d0>

플레이스홀더는 웹에서 악의적인 SQL 명려을 삽입하는 외부 공격 으로 부터 시스템을 보호한다.

curs.execute('SELECT * FROM zoo')

<sqlite3.Cursor at 0x7f2ef56fe9d0>

rows = curs.fetchall()
print(rows)

[(‘duck’, 5, 0.0), (‘bear’, 2, 1000.0), (‘weasel’, 1, 2000.0)]

curs.execute('SELECT * FROM zoo ORDER BY count')

<sqlite3.Cursor at 0x7f2ef56fe9d0>

curs.fetchall()

[(‘weasel’, 1, 2000.0), (‘bear’, 2, 1000.0), (‘duck’, 5, 0.0)]

curs.execute('''SELECT * FROM zoo WHERE damages=(SELECT MAX(damages) FROM zoo)''')

<sqlite3.Cursor at 0x7f2ef56fe9d0>

curs.fetchall()

[(‘weasel’, 1, 2000.0)]

curs.close()
conn.close()

8.4.4 MySQL

8.4.5 PostgreSQL

8.4.6 SQLAlchemy

  • dialect - 데이터베이스 타입
  • driver - 사용하고자 하는 데이터베이스의 특정 드라이버
  • user와 password - 인증문자열, 비밀번호
  • host와 port - DB서버의 위치
  • dbname - 서버에 연결한 DB이름
    import sqlalchemy as sa
    
    conn = sa.create_engine('sqlite://')
    
    conn.execute('''CREATE TABLE zoo
    (critter VARCHAR(20) PRIMARY KEY,
    count INT,
    damages FLOAT)''')
    

<sqlalchemy.engine.result.ResultProxy at 0x7f2ef4eaa438>

ins = 'INSERT INTO zoo (critter, count, damages) VALUES(?, ?, ?)'
conn.execute(ins, 'duck', 10, 0.0)

<sqlalchemy.engine.result.ResultProxy at 0x7f2ef4e9fd68>

conn.execute(ins, 'bear', 2, 1000.0)

<sqlalchemy.engine.result.ResultProxy at 0x7f2ef4e996a0>

conn.execute(ins, 'weasel', 1, 2000.0)

<sqlalchemy.engine.result.ResultProxy at 0x7f2ef4e94588>

rows = conn.execute('SELECT * FROM zoo')
rows

<sqlalchemy.engine.result.ResultProxy at 0x7f2ef4e943c8>

print(rows)

<sqlalchemy.engine.result.ResultProxy object at 0x7f2ef4e943c8>

for row in rows:
print(row)

(‘duck’, 10, 0.0) (‘bear’, 2, 1000.0) (‘weasel’, 1, 2000.0)

SQL 표현언어

meta = sa.MetaData()
print(meta)

MetaData(bind=None) <class ‘sqlalchemy.sql.schema.Table’>

zoo = sa.Table('zoo', meta,
sa.Column('critter', sa.String, primary_key=True),
sa.Column('count', sa.Integer),
sa.Column('damages', sa.Float))

meta.create_all(conn)
conn.execute(zoo.insert(('bear2', 2, 1000.0)))

<sqlalchemy.engine.result.ResultProxy at 0x7f2edeb374a8>

result = conn.execute(zoo.select())
rows = result.fetchall()
print(rows)

[(‘duck’, 10, 0.0), (‘bear’, 2, 1000.0), (‘weasel’, 1, 2000.0), (‘bear2’, 2, 1000.0)]

ORM

import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
conn = sa.create_engine('sqlite:///zoo.db')
Base = declarative_base()
class Zoo(Base):
__tablename__ = 'zoo'
critter = sa.Column('critter', sa.String, primary_key=True)
count = sa.Column('count', sa.Integer)
damages = sa.Column('damages', sa.Float)
def __init__(self, critter, count, damages):
self.critter = critter
self.count = count
self.damages = damages
def __repr__(self):
return "<ZOO({}, {}, {})>".format(self.critter, self.count, self.damages)
Base.metadata.create_all(conn)
first = Zoo('duck', 10, 0.0)
second = Zoo('bear', 2, 1000.0)
third = Zoo('weasel', 1, 2000.0)
first

<ZOO(duck, 10, 0.0)>

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=conn)
session = Session()
session.add(first)
session.add_all([second, third])
session.commit()

Comments