为了账号安全,请及时绑定邮箱和手机立即绑定

如何在Postgres数据库上保存图像文件?

如何在Postgres数据库上保存图像文件?

斯蒂芬大帝 2021-03-20 12:12:57
出于学习目的,我正在使用Python + Flask创建一个网站。我想从数据库中恢复图像并将其显示在屏幕上。但是一次只需要一步。首先,我不知道如何在我的数据库中保存图像。我的搜索仅显示我必须bytea在数据库中使用一种类型。然后,我得到了图像,并以某种方式(??)将其转换为字节数组(bytea ==叮咬阵列?),并以某种方式(??)在插入命令中使用了该阵列。我能够发现(也许)如何用Java(here)和C#(here)做到这一点,但我真的很想使用Python,至少现在是这样。有人能帮我吗?这个站点中有很多此类问题。但是大多数(轻松超过85%)的答复是:“您不应该将图像保存在数据库中,它们属于fs”,并且无法回答问题。其余的并不能完全解决我的问题。因此,如果重复项有这种答案,请不要将其标记为重复项。
查看完整描述

3 回答

?
繁花如伊

TA贡献2012条经验 获得超12个赞

我通常不会为人们编写完整的示例程序,但是您并不需要它,这是一个非常简单的程序,因此,您可以执行以下操作:


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

用Python 3.3编写。使用Python 2.7要求您读取文件并转换为buffer对象或使用大对象函数。转换为Python 2.6及更早版本需要安装argparse,可能还需要进行其他更改。


如果要进行测试运行,则需要将数据库连接字符串更改为适合您的系统的字符串。


如果要处理大图像,请考虑使用psycopg2的大对象支持而不是bytea-特别是lo_import用于存储,lo_export直接写入文件,以及使用大对象读取功能一次读取小块图像。


查看完整回答
反对 回复 2021-03-27
?
慕村225694

TA贡献1880条经验 获得超4个赞

希望这对您有用。


import Image

import StringIO

im = Image.open("file_name.jpg") # Getting the Image

fp = StringIO.StringIO()

im.save(fp,"JPEG")

output = fp.getvalue() # The output is 8-bit String.


查看完整回答
反对 回复 2021-03-27
  • 3 回答
  • 0 关注
  • 594 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号