【问题标题】:Postgresql Data: Array To String ClarificationPostgresql 数据:数组到字符串的说明
【发布时间】:2018-05-03 07:23:23
【问题描述】:

我目前正在处理一项将日期从 PostgreSQL 迁移到另一个 PostgreSQL 数据库的任务。一个字段的数据需要拆分为三列(例如,father_name,需要拆分为 f_name、f_middle_name、f_last_name)我在网上搜索,我认为我可以使用 string_to_array 来完成这项任务。现在我的问题是如何将字符串的数组索引分配给目标数据库的字段(目标数据库有 f_name、f_middle_name、f_last_name 而源数据库只有父亲名称字段)。

    cur_t.execute("""
    SELECT TRANSLATE(studentnumber, '- ', ''), string_to_array(father_name)
    cur_p.execute(""" INSERT INTO "a_recipient" (student_id, f_name,   f_middle_name, f_last_name) VALUES ('%s', '%s', '%s', '%s') """ % (row[0]
row[1][0], row[1][1], row[1][2]))

我只是不知道如何访问数组的索引并将其分配为目标字段的值。

参考:string_to_arraystring_to_array

有什么建议吗?

【问题讨论】:

  • string_to_array 非常适合内联 SQL 使用 - 您不需要在 puthon 中选择然后将结果插入其中
  • 您好,您认为在这个任务中使用 string_to_array 可以吗?或者您可以推荐一些东西吗?

标签: sql database postgresql


【解决方案1】:

虽然it is possible to turn an array into a set of columns 您不会有一组固定的列。例如,如果您将father_name 分成三部分,这对于John Wilkes Booth 来说是可以的,但Yarrow Hock 呢?还是Beyoncé?还是Bernal Diaz Del Castillo?您需要的不仅仅是在空格上拆分更智能。

虽然您可以在 Postgresql 中编写一些东西,可能是 stored procedure,但在 Python 中进行数据转换更容易,但更慢。由于无论如何您都必须通过 Python 运行数据(或者做一些复杂的事情来链接两个数据库),并且由于这是(希望)一次性的,所以性能并不重要。

我不是很擅长 Python,但它会是这样的。

cur_t.execute("""SELECT studentnumber, father_name FROM something""")

for row in cur_t:
    father = parse_name(row['father_name'])
    student_id = fix_studentnumber(row['studentnumber'])

    cur_p.execute("""
        INSERT INTO "a_recipient" (student_id, f_name, f_middle_name, f_last_name)
        VALUES ('%s', '%s', '%s', '%s')
        """ % (student_id, father['first'], father['middle'], father['last'])
    )

然后您将编写parse_name 和fix_studentnumber 以及任何其他必要的函数来清理Python 中的数据。你可以对它们进行单元测试。

注意:因为按数字(即row[5])访问列很难阅读和维护,您可能希望使用conn_t.cursor(cursor_factory=psycopg2.extras.DictCursor),因此您可以像我上面所说的那样按名称访问列。

【讨论】:

  • 注意,谢谢。这需要从 psycopg2 导入额外内容,对吗?我会研究这个。
  • 关于循环内的father和student_id变量的问题,我是否必须对所有字段都这样做才能清理数据?还有你从哪里得到 parse_name 和 fix_studentnumber 的?对不起
  • 搞砸了。漫长的一天。
【解决方案2】:

为什么不直接做n SQL:

vao@so=# create table so12(a text, b text, c text);
CREATE TABLE
vao@so=# with a(i) as (values('1,2,5'))
, s as (select string_to_array(i,',') ar from a)
insert into so12 select ar[1],ar[2],ar[3] from s;
INSERT 0 1
vao@so=# select * from so12;
┌───┬───┬───┐
│ a │ b │ c │
├───┼───┼───┤
│ 1 │ 2 │ 5 │
└───┴───┴───┘
(1 row)

更新 我错过了它发生在多个数据库范围内的观点,因此您需要使用dblink 或创建postgres_fdw 外部表。两者仍然会比选择数组然后使用insert into .. values(..) 语句循环遍历行要快得多

【讨论】:

  • 我在这些表中有 32 列。我们计划以自动化方式执行此操作,因为我们将来可能会有其他类似的任务。
  • 仍然 - 选择 python 然后插入它没有多大意义我会说
  • @VaoTsun 注意他们从一个数据库连接中选择并插入到另一个。
  • @Schwern 是的 - 谢谢你的意见。我仍然确定insert values 会更慢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-06-22
  • 1970-01-01
  • 1970-01-01
  • 2014-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多