如何获取存储在PostgreSQL中的MIME类型的bytea
我们怎样才能得到哑剧类型的bytea如何获取存储在PostgreSQL中的MIME类型的bytea,postgresql,bytearray,postgresql-9.2,postgresql-9.3,bytea,Postgresql,Bytearray,Postgresql 9.2,Postgresql 9.3,Bytea,我们怎样才能得到哑剧类型的bytea 存储在Postgres数据库中?当您首先存储bytea时,除了将MIME类型分配给另一个字段之外,无法确定MIME类型 假设您有未知类型的字节数组来表示文件或其他可能具有MIME类型的合理完整的对象,您可以像对文件一样使用MIME类型猜测工具。这些工具远非十全十美,但对于具有规则和可预测头的常见行为良好的文件类型来说,它们工作得很好 PostgreSQL中没有内置这样的工具,但PostgreSQL支持调用过程语言,如PL/Python和PL/Perl。这些语
存储在Postgres数据库中?当您首先存储
bytea
时,除了将MIME类型分配给另一个字段之外,无法确定MIME类型
假设您有未知类型的字节数组来表示文件或其他可能具有MIME类型的合理完整的对象,您可以像对文件一样使用MIME类型猜测工具。这些工具远非十全十美,但对于具有规则和可预测头的常见行为良好的文件类型来说,它们工作得很好
PostgreSQL中没有内置这样的工具,但PostgreSQL支持调用过程语言,如PL/Python和PL/Perl。这些语言确实有MIME类型猜测工具
因此,我建议在PL/Perl或PL/Python中编写一个包装器函数,使用适当的MIME类型猜测库来探测
bytea
参数并返回猜测的MIME类型。图书馆选择和实施的细节留给读者练习;我将从关于PL/Perl或PL/Python的PostgreSQL手册开始,无论您喜欢使用哪一种。我知道答案有点晚,但会对其他人有所帮助
根据@craig ringer的建议,我已经在plpythonu
中实现了mime魔术,因此我可以在插入/更新触发器中使用该函数
在数据库服务器上,为您的postgresql版本安装plpythonu
(例如,通过apt-get
或yum
)。无需重新启动/重新加载数据库,因此可以在生产环境中轻松完成
然后在数据库服务器上安装python模块magic
:
pip install python-magic
之后,在数据库中创建plpythonu语言:
CREATE LANGUAGE plpythonu;
现在可以用python编写数据库函数(甚至可以导入python模块):
如果使用python2,postgresql的BYTEA
类型映射到python的string
类型。
对于Python3,它映射到pythonsbytes
type
创建函数后,可以像其他postgresql函数一样在任何语句或触发器函数中使用plpythonu函数。
为了测试我们的功能,我们可以创建如下表并插入一些文件:
CREATE TABLE public.files (
file_id BIGINT PRIMARY KEY NOT NULL DEFAULT nextval('files_file_id_seq'::regclass),
name TEXT NOT NULL,
extension TEXT,
content BYTEA NOT NULL,
mime_type TEXT
);
查询示例:
SELECT name, extension, mime_type, mimemagic(content) FROM files;
结果:
name | extension | mime_type | mimemagic
----------------------------------+-----------+-----------+-----
10868_170915_1M | pdf | | application/pdf
30567_160415_1M | pdf | | application/pdf
Diode-SCS | dxf | | text/plain
Config | zip | | application/zip
btn-default-medium-focus-corners | gif | | image/gif
_loadmask | scss | | text/plain
mr | json | | text/plain
10549_160415_2M | pdf | | application/pdf
disconnect | png | | image/png
name | extension | mime_type
------------------------------------------+-----------+------------------------------
teamviewer_10.0.35509_amd64 | deb | application/x-debian-package
BDFE999CCC39110229563FA8C8583E239F6BDBA1 | log | text/plain
daccr-Download | exe | application/x-dosexec
如您所见,表中未保存mime_类型,但会根据需要检测到mime类型
不用说,对每个查询的每一行执行一个函数会对性能造成巨大影响,因此应该在插入/更新时进行mime类型检测并缓存:
触发器示例:
CREATE OR REPLACE FUNCTION files_trigger()
RETURNS TRIGGER AS $$
BEGIN
IF (TG_OP = 'INSERT') OR (TG_OP = 'UPDATE' AND new.content IS DISTINCT FROM old.content)
THEN
new.mime_type := mimemagic(new.content);
END IF;
RETURN new;
END
$$ LANGUAGE plpgsql;
CREATE TRIGGER files_insertupdate_trigger BEFORE INSERT OR UPDATE ON files
FOR EACH ROW EXECUTE PROCEDURE files_trigger();
Mime类型现在检测一次并保存在filecontent旁边:
SELECT name, extension, mime_type FROM files;
结果:
name | extension | mime_type | mimemagic
----------------------------------+-----------+-----------+-----
10868_170915_1M | pdf | | application/pdf
30567_160415_1M | pdf | | application/pdf
Diode-SCS | dxf | | text/plain
Config | zip | | application/zip
btn-default-medium-focus-corners | gif | | image/gif
_loadmask | scss | | text/plain
mr | json | | text/plain
10549_160415_2M | pdf | | application/pdf
disconnect | png | | image/png
name | extension | mime_type
------------------------------------------+-----------+------------------------------
teamviewer_10.0.35509_amd64 | deb | application/x-debian-package
BDFE999CCC39110229563FA8C8583E239F6BDBA1 | log | text/plain
daccr-Download | exe | application/x-dosexec
为了获得更好的结果,如果可用,还应该尝试基于filename/-extension的检测,因为只有mimemagic无法检测某些类型(json文件被检测为text/plain)。
还可以使用magic的选项,如uncompress=True
,这可能会提供更有用的结果:
>>> import magic
>>> import mimetypes
>>> filename='verybig.json.gz'
>>> m=magic.Magic(mime=True, uncompress=False)
>>> m.from_file(filename)
'application/gzip'
>>> m=magic.Magic(mime=True, uncompress=True)
>>> m.from_file(filename)
'text/plain'
>>> mimetypes.guess_type(filename)
('application/json', 'gzip')
>>>
plpythonu的文档可在以下位置找到:
python神奇模块的代码和文档可以在这里找到:首先将其存储在另一列中。您能告诉我关于PL/Perl或PL/python脚本的情况,以及如何在Postgres中应用它们。@ripunj2408813。您需要使用适当的库(如Perl的
File::Type
或Python的mimetypes或Python Magic库)用Perl或Python编写一个过程。试一试。如果您陷入困境,请发布一个新问题,并提供适当的详细信息,说明您尝试了什么以及您陷入困境的地方。我不知道Perl脚本。您能否提供Perl脚本以获取Postgres中bytea的mime类型。@ripunj2408813请尝试自己编写。你可能需要先学习一下。堆栈溢出不是一种代码编写服务,虽然我很乐意提供帮助,但只有在您做出一些努力的情况下,我才会这样做。请参阅我最后一个链接中的文档。