나는 보통 사람들을위한 완전한 예제 프로그램을 작성하지 않지만, 당신이 그것을 요구하지 않았고 당신이 가고, 그래서 여기에 아주 간단한 하나 :
#!/usr/bin/env python3
import os
import sys
import psycopg2
import argparse
db_conn_str = "dbname=regress user=craig"
create_table_stm = """
CREATE TABLE files (
id serial primary key,
orig_filename text not null,
file_data bytea not null
)
"""
def main(argv):
parser = argparse.ArgumentParser()
parser_action = parser.add_mutually_exclusive_group(required=True)
parser_action.add_argument("--store", action='store_const', const=True, help="Load an image from the named file and save it in the DB")
parser_action.add_argument("--fetch", type=int, help="Fetch an image from the DB and store it in the named file, overwriting it if it exists. Takes the database file identifier as an argument.", metavar='42')
parser.add_argument("filename", help="Name of file to write to/fetch from")
args = parser.parse_args(argv[1:])
conn = psycopg2.connect(db_conn_str)
curs = conn.cursor()
# Ensure DB structure is present
curs.execute("SELECT 1 FROM information_schema.tables WHERE table_schema = %s AND table_name = %s", ('public','files'))
result = curs.fetchall()
if len(result) == 0:
curs.execute(create_table_stm)
# and run the command
if args.store:
# Reads the whole file into memory. If you want to avoid that,
# use large object storage instead of bytea; see the psycopg2
# and postgresql documentation.
f = open(args.filename,'rb')
# The following code works as-is in Python 3.
#
# In Python 2, you can't just pass a 'str' directly, as psycopg2
# will think it's an encoded text string, not raw bytes. You must
# either use psycopg2.Binary to wrap it, or load the data into a
# "bytearray" object.
#
# so either:
#
# filedata = psycopg2.Binary(f.read())
#
# or
#
# filedata = buffer(f.read())
#
filedata = f.read()
curs.execute("INSERT INTO files(id, orig_filename, file_data) VALUES (DEFAULT,%s,%s) RETURNING id", (args.filename, filedata))
returned_id = curs.fetchone()[0]
f.close()
conn.commit()
print("Stored {0} into DB record {1}".format(args.filename, returned_id))
elif args.fetch is not None:
# Fetches the file from the DB into memory then writes it out.
# Same as for store, to avoid that use a large object.
f = open(args.filename,'wb')
curs.execute("SELECT file_data, orig_filename FROM files WHERE id = %s", (int(args.fetch),))
(file_data, orig_filename) = curs.fetchone()
# In Python 3 this code works as-is.
# In Python 2, you must get the str from the returned buffer object.
f.write(file_data)
f.close()
print("Fetched {0} into file {1}; original filename was {2}".format(args.fetch, args.filename, orig_filename))
conn.close()
if __name__ == '__main__':
main(sys.argv)
파이썬 3.3으로 작성되었습니다. Python 2.7을 사용하려면 파일을 읽고 buffer
객체로 변환하거나 대형 객체 함수를 사용해야합니다. Python 2.6 및 그 이전 버전으로 변환하려면 argparse를 설치해야합니다. 아마도 다른 변경 사항이 필요합니다.
테스트를 실행할 경우 데이터베이스 연결 문자열을 시스템에 적합한 것으로 변경해야합니다.
당신이 psycopg2's large object support 대신 bytea
사용을 고려 큰 이미지로 작업하는 경우 - 파일에 직접 쓰기 위해, lo_export
저장소에 대한 lo_import
, 특히, 그리고 대형 개체가 한 번에 이미지의 작은 덩어리를 읽는 기능을 읽어 .
내 솔루션입니다
bytea 외에 "대형 개체"도 사용할 수 있습니다. [여기에 매뉴얼 링크가있는 옵션 목록이 있습니다.] (http://stackoverflow.com/questions/7434530/storing-long-binary-raw-data-strings/7439642#7439642) Python 특정 솔루션은 없습니다. –
좋아, 아니 파이썬 특정. 그래서 일반적으로 말하면 이미지와 무엇을해야합니까? 파일을 가져 와서 문자열로 변환 하시겠습니까?문자열을 가져 와서 바이너리로 만드시겠습니까? 내가 이해하지 못하는 것은 당신의 fs에서 "image.jpg"와 그것의 바이트 데이터를 갖는 것 사이에서 일어나는 일이다. –