본문 바로가기

Phython

DBMS / ORM 시작

오전 - JOIN 


SQLLITE

서버가 없어도 잘 작동하도록 만듦. 

DATA TYPE

- NULL

- INTEGER

- REAL

- TEXT

- BLOB

 


                 server

PYHTON    DBMS - DB

Client ---> connection

cursor---> 작업공간

con - cur 

 

con = sqlite3.connect('경로 file path를 적어줘도 되고, in-memory상태에서 작업 가능')

cur=con.cursor()
con.close()  # 작업이 끝나면 db닫기
dir(cur)
cur.execute('SQL문 1개')
cur.executemany('SQL문이 1개가 반복 실행됨')
cur.executescript('SQL문 여러개 한 번에 실행') #비표준 방법

ppt 속 예제 만들어보기 


1. city 테이블 만들고  create

cur.execute('''
        CREATE TABLE CITY(
            CNO INTEGER PRIMARY KEY,
            CNAME TEXT
        )
            ''')

2. 데이터 입력하기   insert into 

cur.execute('''
    INSERT INTO CITY(CNP, CNAME)
    VALUES(1, "London");
            ''')


cur.execute('''
    INSERT INTO CITY
    VALUES(2, "Paris");
            ''')


cur.execute('''
    INSERT INTO CITY(CNAME)
    VALUES("Rome");
            ''')
 
cur.execute('''
    INSERT INTO CITY
    VALUES(NULL, "Vienna");
            ''')

 

3. 가져오기

** DB에 저장되어 있는 데이터를 메모리에 불러놓고, FETCH를 통해서 꺼내 쓴다고 생각하면 편함. 

   FETCH로 꺼내 쓰면 메모리 안에는 그 데이터가 없다. 

cur.fetchone ('Tuple/Record/Row 1개')
cur.fetchmany('N개')
cur.fetchall('All')

FETCH 하기 위해서는 먼저 데이터를 다 가져와야 한다.  select

cur.execute('SELECT * FROM CITY')

이렇게 가져오면, 이제 FETCH가능 (fetch를 하면 db의 데이터를 메모리상으로 불러온다.)

cur.fetchone ()

>>> cur.fetchone ()
(2, 'Paris')
>>> cur.fetchone ()
(3, 'Rome')
>>> cur.fetchone ()
(4, 'Rome')
>>> cur.fetchone ()
(5, 'Vienna')

FETCHONE은 ITERATE 하기 때문에 데이터가 더이상 없을 때까지 순차적으로 불러온다. 

cur.fetchmany(2)

>>> cur.fetchmany(2)
[(2, 'Paris'), (3, 'Rome')]
>>> cur.fetchmany(2)
[(4, 'Rome'), (5, 'Vienna')]

데이터를 2개씩 불러와도 iterate 하기 때문에 없을때까지 나온다. 

cur.fetchall()

>>> cur.fetchall()
[(2, 'Paris'), (3, 'Rome'), (4, 'Rome'), (5, 'Vienna')]

fetchall 을 사용하면 한 번에 다 불러올 수 있다. 

 

 

변수를  방법

1. qmark 


1. SUPPLIER 테이블 만들기 

cur.execute('''
        CREATE TABLE SUPPLIER(
            SNO INTEGER PRIMARY KEY,
            SNAME TEXT NOT NULL DEFAULT 'NONAME',
            CNO INTEGER NOT NULL
        )
            ''')

2. 데이터 입력하기 - qmark 방식 / named 스타일 방

방법 1. 데이터 한 개 입력

sname = 'Smith'
cno = 1
cur.execute('''INSERT INTO SUPPLIER VALUES(NULL, ?, ?);
            ''', (sname, cno))

 

방법 2. 데이터 여러개 입력 

data = (('Jones', 2), ('Adams', 1), ('Blake', 3))
cur.executemany('''INSERT INTO SUPPLIER VALUES(NULL, ?, ?);
            ''', data)

잘 들어갔는지 확인 

cur.execute('SELECT * FROM SUPPLIER')
cur.fetchall()

>>> cur.fetchall()
[(1, 'Smith', 1), (2, 'Jones', 2), (3, 'Adams', 1), (4, 'Blake', 3)] 

잘 들어갔다. 

 


PART TABLE 만들기

1. 테이블 생성

 

cur.execute('''
        CREATE TABLE PART(
            PNO INTEGER PRIMARY KEY AUTOINCREMENT,
            PNAME TEXT
        )
            ''')

2. 데이터 입력하기

cur.execute('''
    INSERT INTO PART
    VALUES (:pno, :pname)            
''', {'pno':1, 'pname':'screw', 'asdf':'asdf'})
data2 = [{'pname':'Nut'},
         {'pname':'Bolt'},
         {'pname':'Cam'}]

cur.executemany('''
    INSERT INTO PART
    VALUES (NULL, :pname)            
''', data2)

SELLS TABLE 만들기

1. 테이블 생성 

cur.execute('''
    CREATE TABLE SELLS(
        SNO INTEGER NOT NULL,
        PNO INTEGER NOT NULL,
        PRICE INTEGER NOT NULL
    );
            ''')
key1 = 'Screwd'
key2 = 'Smithd'
sno=0
pno=0

cur.execute('''SELECT PNO FROM PART
            WHERE PNAME = ?''', [key1])

rst = cur.fetchone()
if rst:
    #결과가 있을 때
    pno=rst[0]
   


cur.execute('''SELECT PNO FROM PART
            WHERE PNAME = ?''', [key2])

rst = cur.fetchone()
if rst:
    #결과가 있을 때
    sno=rst[0]
   
pno,sno

문제의 에러 발생 구간.. 인 줄 알았는데, 테이블 다시 만들고 바로 밑에 코드 실행하면 에러 안 난다. 신기방기.

data = ['Smith', 'Screw', 10]
cur.execute('''
    INSERT INTO SELLS
    VALUES(
        (SELECT SNO FROM SUPPLIER WHERE SNAME=? LIMIT 0, 1),
        (SELECT PNO FROM PART WHERE PNAME=? LIMIT 0, 1),
        ?
    )
''', data)
#LIMIT으로 조건 걸기 (0번쨰 위치에서 딱 하나만 가져오기)

잘 들어갔는지 확인

cur.execute('SELECT * FROM SELLS')
cur.fetchall()

>>> cur.fetchall()
[(1, 1, 10)]


지금까지 코드는 DBMS에서 작업하는 방법.

지금부터는 CODE LEVEL 에서 딕셔너리 만든는 방법.

내가 지금 어디에서 만들고 있는지 확인하는게 중요!

 

\

 

 
#p.73 따라하기 - 집계함수 살짝 섞어보기
cur.execute('''
    SELECT S.SNAME, C.CNAME , COUNT(*)
    FROM SUPPLIER AS S, CITY AS C
    WHERE S.CNO = C.CNO
    GROUP BY S.SNAME
    ORDER BY C.CNO ASC
''')
cur.fetchall()

 

## 다시 물리적인 형태의 DB 만들기
con = sqlite3.connect('0905.db')
cur = con.cursor()

cur.execute('''
    CREATE TABLE PART (
        PNO INTEGER PRIMARY KEY,
        PNAME TEXT
    )
''')

cur.executescript('''
    INSERT INTO PART (PNO, PNAME) VALUES (1, 'Screw');
    INSERT INTO PART (PNAME) VALUES ('Bolt');
    INSERT INTO PART (PNAME) VALUES ('Nut');
    INSERT INTO PART (PNO, PNAME) VALUES (4, 'Cam');
''')
 
cur.execute('INSERT INTO PART VALUES(NULL, "Part1")')

cur.execute('SELECT * FROM PART')
cur.fetchall()

>>> cur.fetchall()
[(1, 'Screw'), (2, 'Bolt'), (3, 'Nut'), (4, 'Cam'), (5, 'Part1')]

 

 

 


ORM -> SQLAlchemy 사용

core 단 위에 orm 단이 있는 구조. 

command창에 입력해서 다운 받기.

!pip install SQLAlchemy

새롭게 db 생성.

con.close()
con = sqlite3.connect('sns.db')
cur = con.cursor()

 

cur.executescript('''
    CREATE TABLE POST(
        PK INTEGER PRIMARY KEY,
        CONNECT TEXT
    );
    CREATE TABLE HASHTAG(
        PK INTEGER PRIMARY KEY,
        COUNT INTEGER DEFAULT 0,
        NAME TEXT
    );
    CREATE TABLE POSTTAG(
        PPK INTEGER NOT NULL,
        HPK INTEGER NOT NULL
    );
''')