如何基于numpy数据类型确定PostgreSQL列数据类型?

时间:2019-04-28 13:37:06

标签: python postgresql numpy psycopg2

在Python方面,我有一个信号列表,每个信号都是numpy.ndarray

在dtype变化的信号中-包括numpy.uint8numpy.uint16numpy.uint32numpy.float64numpy.bytes_

最终,我想将信号传递给PostgreSQL中的一个表,每个信号都是一列。现在,我被困在“添加列”步骤中,因为需要为PostgreSQL中的每一列指定数据类型。

当我使用psycopg2作为适配器时,我在文档中找到了this table,但没有找到任何信息来帮助以动态方式添加具有适当数据类型的列。

我的想法/方法是-考虑到我所拥有的信号中只有5个已知的dtype,我可以:

  1. 遍历信号列表
  2. 获取每个信号的第一个元素,找到其dtype
  3. 为每个信号确定适当的PostgreSQL数据类型
  4. 生成相应的PostgreSQL数据类型列表
  5. 添加列时使用生成的列表传递数据类型

我不确定这是否是最佳方法。有现成的lib可以完成这项工作吗?还是有更好的方法编码这种方法?

感谢您的见解!

1 个答案:

答案 0 :(得分:0)

一点都不优雅,但最终我使用了这种方法:

读取每个信号中第一个元素的type()并将其转换为str,随后将其传递给一个函数,以基本匹配相应的PostgreSQL数据类型。 请注意,仅涵盖与我的项目相关的numpy数据类型。

def db_data_type(data_type):
    # Input is string of data type
    conversion_table = {
        "<class 'numpy.uint8'>":    'int2',     # 0 to 255          # -32768 to 32767
        "<class 'numpy.uint16'>":   'int4',     # 0 to 65535        # -2147483648 to 2147483647
        "<class 'numpy.uint32'>":   'int8',     # 0 to 4924967295   # -9223372036854775808 to 9223372036854775807
        "<class 'numpy.int8'>":     'int2',     # -128 to 127
        "<class 'numpy.int16'>":    'int2',     # -32768 to 32767
        "<class 'numpy.int32'>":    'int4',     # -2147483648 to 2147483647
        "<class 'numpy.float64'>":  'float8',   # double
        "<class 'numpy.bytes_'>":   'text',
    }
    return conversion_table[data_type]

基本上,当我遍历一堆信号(数据库表中的列)时,我将获得信号名称列表(DB中的列名称)和数据类型列表(DB中的列数据类型)。这是psycopg2生成SQL查询的代码:

def db_create_columns(conn, table, columns, types):
    cur = conn.cursor()
    for i in range(len(columns)):
        sql_add_column = psycopg2.sql.SQL("""ALTER TABLE {} ADD COLUMN {} {} ;""") \
            .format(psycopg2.sql.Identifier(table),
                    psycopg2.sql.Identifier(columns[i]),
                    psycopg2.sql.Identifier(types[i]))
        try:
            cur.execute(sql_add_column)
        except Exception as e:
            print('Error occurred when adding data column [%s].\n%s' % (columns[i], e))
    cur.close()
    conn.commit()
    return

这里的函数参数是:与数据库的连接,表名,列名列表,数据类型列表。

如果有更好的方法可以做到这一点,请毫不犹豫地指出。非常感谢。