PostgreSQL
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> PostgreSQL

Làm cách nào để lưu tệp hình ảnh trên cơ sở dữ liệu Postgres?

Tôi thường không viết các chương trình ví dụ hoàn chỉnh cho mọi người, nhưng bạn không yêu cầu nó và nó là một chương trình khá đơn giản, vì vậy bạn hãy bắt đầu:

#!/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)

Được viết bằng Python 3.3. Sử dụng Python 2.7 yêu cầu bạn đọc tệp và chuyển đổi sang buffer đối tượng hoặc sử dụng các chức năng đối tượng lớn. Chuyển đổi sang Python 2.6 trở lên yêu cầu cài đặt argparse, có thể là các thay đổi khác.

Bạn sẽ muốn thay đổi chuỗi kết nối cơ sở dữ liệu thành chuỗi nào đó phù hợp với hệ thống của mình nếu bạn định chạy thử.

Nếu bạn đang làm việc với hình ảnh lớn, hãy cân nhắc sử dụng psycopg2's hỗ trợ đối tượng lớn thay vì bytea - cụ thể là lo_import cho cửa hàng, lo_export để ghi trực tiếp vào tệp và chức năng đọc đối tượng lớn để đọc các phần nhỏ của hình ảnh cùng một lúc.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bỏ qua dấu ngoặc kép khi nhập tệp CSV vào PostgreSQL?

  2. không thể dịch postgres tên máy chủ sang địa chỉ:Tên hoặc dịch vụ không được biết

  3. Chèn hàng loạt vào Postgres với brianc / node-postgres

  4. Xóa các hàng trùng lặp (không xóa tất cả các hàng trùng lặp)

  5. Làm thế nào để so khớp not null + not rỗng?