파이썬 파일 입출력

기본형태

1
f = open('file name', 'mode')

f - 파일 객체

file name - 파일 문자열 이름

mode - 파일 타입과 무엇을 할지

mode

r - 파일 읽기

w - 파일 쓰기

x - 파일 쓰기(파일이 존재하지 않을 경우)

a - 파일 추가(파일이 존재하면 기존의 내용의 뒤에 추가)


mode의 두번째 글자 - 파일타입 지정

t(또는 아무것도 명시하지 않음) - 텍스트 타입

b - 이진 타입

텍스트 파일 쓰기

write()

1
2
3
f = open('test.txt', 'w')
f.write('first sentence')
f.close() # 꼭 닫아주어야 한다

텍스트 파일을 쓰는 방법

  1. write()
  2. print()

위의 예제를 print()을 통해서 쓰려면

1
2
3
f = open('test.txt', 'w')
print('first sentence', file=f)
f.close()

기본적으로 print()는 각 인자 뒤에 스페이스를, 끝에 줄바꿈을 추가한다

print()를 write() 처럼 작동하려면 print()에 다음 두 인자를 전달해야 한다

  • sep(구분자) - 기본값은 ‘ ‘ 스페이스 이다
  • end(문자열 끝) - 기본값은 ‘\n’ 줄바꿈 이다

텍스트 파일 읽기

read(), readline(), readlines()

  1. read()

인자 없이 호출하여 한 번에 전체 파일을 읽을 수 있다

엄청 큰 파일을 read()로 읽으면 메모리 소비가 심하므로 주의!!

1
2
3
4
5
f = open('test.txt', 'r')
contents = f.read()
f.close()

print(contents)
  • 읽기 + 쓰기
    • 파일 안의 내용을 확인하여 내용을 추가하는 경우가 생길 수 있다.
    • 읽기용 파일 객체와 쓰기용 파일 객체를 따로 생성하는 것이 아니라 읽기 / 쓰기를 동시에 수행할 수 있는 파일 객체를 생성하면 된다
    • 읽기 / 쓰기를 둘 다 하고 싶을대는 r+모드를 사용하면 된다
1
2
3
4
f = open('test.txt', 'r+')
f.read() # 모든 내용 출력
f.write('hello world') # 해당 문자열을 저장 후 글자수 리턴
f.read() # 빈 문자열 출력

위 와 같은 문제가 발생하는 이유는 첫 번째 read() 메소드를 사용했을 때 파일을 읽는 위치가 변했기 때문이다. read() 메소드를 사용하면 읽은 만큼 커서가 뒤로 이동했기 때문에 다시 read() 를 호출한다 한들 빈 문자열이 출력되는 것이다.
read 메소드를 사용한 뒤 다시 파일의 처음부터 읽으려면 커서의 위치를 처음으로 옮겨주어야 하는데 seek 메소드를 통해서 할 수 있다.

1
2
3
4
5
f = open('test.txt', 'r+')
f.read() # 커서 맨 뒤로 이동
f.read() # 빈 문자열 출력
f.seek(0) # 파일의 맨 앞으로 커서 이동
f.read() # 모든 내용 출력
  1. readline()

파일을 라인 단위로 읽는다

1
2
3
4
5
f = open('test.txt', 'r')
a = f.readline()
f.close()

print(a) # 첫번째 줄만 읽어서 출력
  1. readlines()

한 번에 모든 라인을 읽고, 한 라인으로 된 문자열들의 리스트를 반환한다

1
2
3
4
5
6
f = open('test.txt', 'r')
a = f.readlines()
f.close()

for line in a:
print(line, end='')

with를 이용한 예제

1
2
with open('sample.txt', 'w') as f:
f.write('example sentence')

context manager 코드 블록의 코드가 실행이 되고나서 자동으로 파일을 닫아준다

CSV

Comma-Seperated-Values

  • 쓰기 예제
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import csv

lists = [
['a', 'first'],
['b', 'second'],
['c', 'third'],
['d', 'fourth'],
['e', 'fifth'],
['f', 'sixth']
]

with open('test2.txt', 'w') as f:
csvout = csv.writer(f)
csvout.writerows(lists)
  • 읽기 예제(List)
1
2
3
4
5
import csv

with open('test2.txt', 'r') as f:
var = csv.reader(f)
lists = [row for row in var]
  • 읽기 예제(Dictionary)
1
2
3
4
5
import csv

with open('test2.txt', 'r') as f:
var = csv.DictReader(f, fieldnames = ['alphabet', 'number'])
aaa = [row for row in var]
Share

시놀로지 나스와 함께하는 git server

시놀로지 4베이짜리 나스에 git server를 설치해보고자 한다!

시놀로지와 함께하는 깃 서버

갑자기 시놀로지 나스에 git server를 설치하게됐다. 평소 깃허브는 자주 사용해왔지만 이번기회에 조금 더 알아보기로 했다.

비슷한 서비스로는 gitgithub 그리고 gitlab이 있다. 모두 저장소를 public 하게 사용한다면 무료로 사용할 수 있고, gitlab의 경우에는 저장소당 1GB의 제한이 있다.

본격적으로 시작해보자

1. 시놀로지에 git server 패키지 설치

패키지 센터를 통해서 설치하면 된다.

2. SSH 서비스 활성화

이동경로: 제어판 > 터미널 및 SNMP > SSH 서비스 활성화
SSH 서비스 활성화를 체크해 활성화한다. 아마도 기본적으로 22번 포트로 설정되어 있을텐데 취향에 따라 고르면된다.

3. 사용자 홈 서비스 활성화

이동경로: 제어판 > 사용자 > 고급 > 사용자 홈 서비스 활성화
2번과 마찬가지로 체크하여 사용자 홈 서비스 활성화 해준다.

4. git server 접근 허용

깃 서버를 설치했다면 바탕화면에 아이콘이 있을 것이다. git을 사용할 수 있는 사용자를 설정할 수 있는데 해당하는 계정을 체크해준다.

5. 시놀로지 접속

1
ssh -p PORT USERNAME@ADDRESS

로그인 할 유저네임과 나스 주소를 입력하여 접속한다.
나스에 접속하여 원하는 폴더로 이동한 후 원격저장소를 만들어주면 된다. 나의 경우 원격 저장소를 만드는 것과 테스트하기 위해 로컬에서 git remote add 하는 것에 어려움을 겪었다.

구성

시놀로지 나스에 git server를 설치하고 이용할때 다음과 같은 구성으로 사용하는 게 일반적인듯 샆다.

계정 생성

  1. git-admin
    • git user 관리
    • 저장소별 권한 관리
  2. git-repo
    • git 저장소 관리

git server에 각 각의 아이디로 로그인하려면 다음과 같이 한다.

1
ssh <USERNAME>@<IP_ADDRESS>

서버에 ssh로 로그인 후 여러 프로젝트를 관리할 디렉터리(repos)를 원하는 경로에 생성한다.

repos 디렉터리 안에 저장소를 생성한다. 일반적으로 저장소의 이름은 PROJECT_NAME.git 으로 작성한다.

1
2
# repos/
mkdir test.git

원격(remote) 저장소는 워킹 디렉터리(working directory)가 없다.
일반적인 로컬 저장소를 생성하는 명령어(git init)에 --bare 옵션을 줌으로써 워킹 디렉터리가 없는 원격 저장소를 생성한다.
이때에 --shared 옵션을 주면 자동으로 그룹 쓰기 권한을 추가해준다.

Share

python과 PostgreSQL 연동하기

PostgreSQL은 오픈소스 관계형데이터베이스(RDBMS)이다. 오픈소스 진영의 RDBMS 중에서 두 번째로 큰 사용자층을 가지고 있으며 가장 많이 사용되는 DB는 MySQL이다. 처음 접해본 DBMS가 postgresql이었기 때문에 현재고 가끔식 사용하는 중이다.

이용중인 운영체제에 따라서 설치하는 방법이 조금씩 다르며, 같은 운영체제라고 해도 CLI와 GUI로 구분함에 따라 또 나뉘어진다.

설치

  • in OSX
    먼저 맥에서 어떻게 설치해야 하는지 알아보자. 공식홈페이지에서 배포하고있는 gui 기반의 소프트웨어도 있지만, 터미널에서 사용하기 위해 Homebrew를 통해 설치를 진행해본다.
    1
    2
    brew update # 먼저 homebrew를 업데이트해준다
    brew install postgresql # psql 설치
    두 번재 명령을 통해서 psql을 설치할 수 있다. 설치는 매우 간단하다.

psql을 처음 설치했다면 db를 만들기 위해 아래와 같이 입력한다.

1
initdb /usr/local/var/postgres -E utf8

데몬을 통해 db서버를 항상 띄워놓을 수도 있지만 다음 명령어로 수동으로 실행하고 종료할 수 있다.

1
2
pg_ctl -D /usr/local/var/postgres start # 실행
pg_ctl -D /usr/local/var/postgres stop -s -m fast # 종료

기본 명령어

설치까지 완료하였고 python과 연동하기에 앞서서 가장 기초적인 명령어를 살펴보자.

  • 클라이언트 접속

    1
    psql <db_name>

    클라이언트에 접속하기 위해서 psql이라는 명령어를 사용해야한다. 뒤에는 db명을 명시해야하며 비밀번호를 요구할 수도 있다.

  • 데이터베이스 목록 확인

    1
    \l

    현재 데이터베이스의 목록을 출력하는 명령어는 \l(역슬래시 + 영소문자 L)이다. 아마도 기본적으로 postgres와 template0 그리고 template1이 있을것이다. 또한 프롬프트를 통해 현재 어떠한 데이터베이스에 접속해 있는지도 알 수 있다.

  • 데이터베이스 변경

    1
    \c <db_name>

    사용중인 데이터베이스를 변경한다. 명령어는 \c(역슬래시 + 영소문자 C) 이다. 정상적으로 변경이 완료되었다면 프롬프트(쉘)의 이름이 변경된 것을 확인할 수 있다.

  • 새로운 데이터베이스 생성

    1
    CREATE DATABASE <db_name>;

    새로운 데이터베이스를 생성하며 자동으로 로그인 중인 db를 변경해준다. 소문자로 적어도 작동은 하는 것 같고.. 문장 끝에 세미콜론을 잊으면 안된다.

  • 스키마 목록 확인

    1
    \dn

    스키마 목록을 확인할 수 있다. 데이터베이스를 막 생성한 직후라면 기본적으로 public 밖에 없을 것이다.

  • 테이블 목록

    1
    \dt

    현재 데이터베이스의 테이블 목록을 확인할 수 있다.

  • 클라이언트 종료

    1
    \q

    psql 클라이언트를 종료한다.

  • 테이블 정의

    1
    2
    3
    4
    CREATE TABLE <table_name> (
    column1 datatype,
    column2 datatype,
    );

    이름이 table_name 이고 데이터 타입이 datatype인 컬럼을 두 개 가진 테이블을 생성한다.

  • 테이블 삭제

    1
    DROP TABLE <table_name>

    해당 테이블을 삭제한다. 해당 커맨드는 테이블 자체를 삭제하는 것이며, 테이블의 데이터를 삭제하려고 한다면 DELETE 또는 TRUNCATE 명령을 사용해야 한다.

  • 테이블의 데이터 삭제

    1
    DELETE from <table_name>

    해당 테이블의 모든 데이터를 삭제한다.

지금까지 맥북에서 설치하는 방법과 간단한 명령어를 알아보았다.

python과 연동

간단하게나마 psql에 대해서 접해보았으니 원래 주제인 python과 연동하는 방법을 알아보자. 패키지 의존성 문제를 피하기 위해 virtualenv와 같은 가상환경을 이용하도록 하자.

실습을 위한 가상환경을 생성했으면 잊지말고 활성화를 하자. psql을 python에서 사용하려면 driver(adapter)를 이용해야만 한다. psql을 파이썬과 함께 사용할때 가장 많이 쓰이는 드라이버는 psycopg2이다. psycopg2란 파이썬을 위한 가장 알려진 psql db adapter 라고 공식문서에서 소개하고 있으며 주된 기능으로는 thread safety와 파이썬 db api 2.0을 완벽하게 수행하는 것이라고 한다.

  • psycopg2 설치

    1
    pip3 install psycopg2

    매우 간단하다.

  • 연동

    1
    2
    3
    4
    import psycopg2 # driver 임포트

    # conn = psycopg2.connect("host=localhost dbname=test user=postgres password=pwtest port=5432")
    conn = psycopg2.connect(host='localhost', dbname='test', user='postgres', password='pwtest', port='5432') # db에 접속

    먼저 설치한 psycopg2를 임포트한다. 그 다음으로 psql db에 접속할 차례인데 위의 예제코드처럼 두 가지 방법이 있다. 첫 번째는, 연결옵션들을 모두 하나의 따옴표(“”)안에 넣는 방법이고 두 번째 방법은 각각의 연결옵션마다 개별적으로 적어주는 방법이다.

    1
    2
    cur = conn.cursor() # 커서를 생성한다
    # 특정한 처리를 할때 사용함

    커서를 생성했다. 커서란 select 되는 특정 집합에 대해서 각 행에 대해 특정한 처리를 할 때 사용한다고 한다.(결과로 도출된 데이터에서 특정 위치, 특정 row를 가리킬 때 사용된다)

    1
    2
    3
    4
    5
    # 명령 실행 : 새 테이블 만들기
    cur.execute("CREATE TABLE test_table (title varchar, content text);")

    # data 입력
    cur.execute("INSERT INTO test_table (title, content) VALUES (%s, %s)", ('hello' ,'qwerttyfdas'))

    생성한 커서를 가지고 명령을 수행하는 코드이다. execute()안에 psql 명령어를 입력하면 된다.

    데이터를 집어넣는 명령을 수행할때 주의해야할 것들이 있다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # example 1
    cur.execute("INSERT INTO numbers VALUES (%d)", (42,)) # WRONG
    cur.execute("INSERT INTO numbers VALUES (%s)", (42,)) # correct

    # example 2
    cur.execute("INSERT INTO foo VALUES (%s)", "bar") # WRONG
    cur.execute("INSERT INTO foo VALUES (%s)", ("bar")) # WRONG
    cur.execute("INSERT INTO foo VALUES (%s)", ("bar",)) # correct
    cur.execute("INSERT INTO foo VALUES (%s)", ["bar"]) # correct

    # exampel 3
    SQL = "INSERT INTO authors (name) VALUES (%s);" # Note: no quotes
    data = ("O'Reilly", )
    cur.execute(SQL, data) # Note: no % operator

    ex1 - 숫자형이라고 placeholder를 %d로 입력하지 않는다.
    ex2 - 튜플로 넘겨줄땐 항상 following comma가 필요하며 리스트로 넘겨주는 것 또한 가능하다.
    ex3 - 또한 .execute()안에 명령어를 직접 입력해주는 것 보다 수행할 sql문과 대입할 data을 따로 넘겨주는 것을 선호한다.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # test 테이블의 모든 데이터를 가져오고 출력한다
    cur.execute("SELECT * FROM test;")
    print cur.fetchone()

    # 데이터를 변경했다면 반드시 .commit() 해주어야 한다
    conn.commit()

    # 커서를 닫고 연걸을 종료한다.
    cur.close()
    conn.close()

    잊지말고 conn.commit()을 해주어야 삭제했던 변경했던 새로 데이터를 추가했던간에 실제 db에 반영이된다. 매번 commit을 하지 않아서 왜 db에 값이 저장되지 않을까? 하는 실수를 반복하고 있다.


[참고]
https://gist.github.com/xpepper/8110743
http://blog.naver.com/PostView.nhn?blogId=alice_k106&logNo=220847310053
http://www.sqler.com/400339
http://blog.secretmuse.net/?p=24
http://freeprog.tistory.com/100

Share