【问题标题】:How can I INSERT a python object into postgreSQL [duplicate]如何将 python 对象插入到 postgreSQL [重复]
【发布时间】:2020-07-06 14:12:13
【问题描述】:

我在stackoverflow中发现了这个问题saving python object in postgres table with pickle

我有一个创建一些对象的 python 脚本。我希望能够将这些对象保存到我的 postgres 数据库中以供以后使用。 根据@SergioPulgarin 的评论,我尝试了以下方法!

存储:

  1. 将对象腌制为二进制字符串 pickle_string = pickle.dumps(object)
  2. 将 pickle 字符串存储在 postgres 的 bytea(二进制)字段中。在 Psycopg2 中使用简单的 INSERT 查询

检索:

  1. 选择 Psycopg2 中的字段。 (简单的 SELECT 查询)
  2. Unpickle 解码结果retrieve_pickle_string = pickle.loads(decoded_result)

我转储了泡菜文件。现在我正在尝试将其加载到数据库中。我的问题是我找不到正确的语法来做到这一点......

我已经在一个带有 psycopg2 的 python 文件中尝试过它:我已经转储了 pickle 对象并连接到数据库。我尝试将数据类型更改为字节,然后将泡菜插入数据库:

pickle_obj = bytes(pickle_file)
query = "INSERT INTO schema.table (col1, ...) VALUES (%%s, ...)" % pickle_obj
cursor.execute(query)

我收到了这个错误:

Traceback (most recent call last):
  File "/path/to/file.py", line 18, in <module>
    cursor.execute(query)
psycopg2.errors.SyntaxError: syntax error at or near "K"
LINE 1: ...e1_h\x15Nh\x16K\x00h\x17Nh\x18Nh\x19\x89h&K\x0bh\'K\x01h(h+h...
                                                         ^

进程以退出代码 1 结束

然后我尝试将它直接从 postgreSQL 插入(但我也不确定这段代码,因为它不能正常工作。)

INSERT INTO table SELECT PG_Read_File('/home/...)

我认为我的语法不是 100% 正确?那么你是怎么做到的呢?感谢您的提示!

尝试使用文档中所述的 psycopg2.Binary 包装此对象。 https://www.psycopg.org/docs/usage.html#adapt-binary

这些帖子似乎已被删除,但因为它对我有用,所以我只是在此处添加它。谢谢!

【问题讨论】:

    标签: python postgresql pickle


    【解决方案1】:

    您应该始终使用参数化查询将值替换为查询。字符串构造或格式化会使您面临 SQL 注入攻击。除了安全优势之外,使用参数化查询还允许驱动程序为您处理转义和引用。

    完成您所要求的最短路径是在表中使用bytea 列。

    如果您的表格如下所示:

      Column   |  Type   
    -----------+---------
     id        | integer serial primary key
     bytesdata | bytea   
    

    那么这个insert 就可以了:

    cursor.execute("insert into mytable (bytesdata) values (%s) returning id", (pickle_obj, ))
    inserted_id = cursor.fetchone()[0]
    connection.commit()
    

    以后要检索这个对象,可以执行:

    cursor.execute("select bytesdata from mytable where id = %s", (inserted_id, ))
    row = cursor.fetchone()
    retrieved_pickle_obj = row[0]
    

    【讨论】:

    • 我的 id 类型是 SERIAL。我认为串行数据类型会自行添加?这样在输入新行时不必添加它?
    • 你是对的。我修改了上面的答案。
    猜你喜欢
    • 2020-10-25
    • 2018-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-21
    • 2012-02-02
    • 1970-01-01
    相关资源
    最近更新 更多