如何将列对移动到新表,将FK保存到旧表并创建一个值为列名的新列?

时间:2016-01-10 15:11:26

标签: postgresql

我下载的数据库包含国家和城市的翻译,有70种语言(部分翻译是''),但有关城市\国家的翻译和技术信息(人口,旗帜,领土,电话等)保存在同一张表中。

我的意思是每个翻译都有自己的专栏(翻译本身+翻译语言描述),旁边是与翻译无关的其他信息。共约190支列,包括70 * 2(翻译+描述)。

我不认为这是正确的方法,我想将所有翻译移到分隔的表格中,将FK保留在主\技术信息表中。

所以,现在我有一张桌子"城市"结构如下:

id region_id countries_id phone population lang_1 description_1 lang_2  description_2 lang_3  description_3 .... lang_70       description_70
1      1           1       +7       123    Москва  SomeDesc     Moscow  SomeDesc2     Moskwa  SomeText3          Translation70 SomeDesc70
2      1           1       +7       123    Кубинка SomeDesc     Kubinka SomeDesc2     Kubinka    ''              Translation70 SomeDesc70

有2.5M行\城市。

我想移动所有" lang_(1-70)"和他们对新表的描述" cities_translated"应该是这样的:

id cities_id name          description lang
1     1      Москва        SomeDesc    lang_1
2     1      Moscow        SomeDesc2   lang_2
3     1      Moskwa        SomeText3   lang_3
...
70    1      Translation70 SomeDesc70  lang_70
71    2      Кубинка       SomeDesc    lang_1
72    2      Kubinka       SomeDesc2   lang_2
73    2      Kubinka       SomeDesc3   lang_3
...
140   2      Translation70 SomeDesc70  lang_70 

任何人都可以通过正确的查询来帮助我进行此转移吗?

P.S。我已经有一张表"语言"并且作为下一步,我将替换所有值,例如' lang_1',' lang_2'以及适当的FK。

1 个答案:

答案 0 :(得分:0)

希望获得原始的sql解决方案以提高我的sql知识,但由于没有anwers,我决定使用Python。

initial_table = 'countries.city'
init_table_columns = ['lang_1', 'description_1', 'lang_2', 'description_2', 'lang_3', 'description_3', 'lang_4', 'description_4', 'lang_5', 'description_5', 'lang_6', 'description_6', 'lang_7', 'description_7', 'lang_8', 'description_8', 'lang_9', 'description_9', 'lang_10', 'description_10', 'lang_11', 'description_11', 'lang_12', 'description_12', 'lang_13', 'description_13', 'lang_14', 'description_14', 'lang_15', 'description_15', 'lang_16', 'description_16', 'lang_17', 'description_17', 'lang_18', 'description_18', 'lang_19', 'description_19', 'lang_20', 'description_20', 'lang_21', 'description_21', 'lang_22', 'description_22', 'lang_23', 'description_23', 'lang_24', 'description_24', 'lang_25', 'description_25', 'lang_26', 'description_26', 'lang_27', 'description_27', 'lang_28', 'description_28', 'lang_29', 'description_29', 'lang_30', 'description_30', 'lang_31', 'description_31', 'lang_32', 'description_32', 'lang_33', 'description_33', 'lang_34', 'description_34', 'lang_35', 'description_35', 'lang_36', 'description_36', 'lang_37', 'description_37', 'lang_38', 'description_38', 'lang_39', 'description_39', 'lang_40', 'description_40', 'lang_41', 'description_41', 'lang_42', 'description_42', 'lang_43', 'description_43', 'lang_44', 'description_44', 'lang_45', 'description_45', 'lang_46', 'description_46', 'lang_47', 'description_47', 'lang_48', 'description_48', 'lang_49', 'description_49', 'lang_50', 'description_50', 'lang_51', 'description_51', 'lang_52', 'description_52', 'lang_53', 'description_53', 'lang_54', 'description_54', 'lang_55', 'description_55', 'lang_56', 'description_56', 'lang_57', 'description_57', 'lang_58', 'description_58', 'lang_59', 'description_59', 'lang_60', 'description_60', 'lang_61', 'description_61', 'lang_62', 'description_62', 'lang_63', 'description_63', 'lang_64', 'description_64', 'lang_65', 'description_65', 'lang_66', 'description_66', 'lang_67', 'description_67', 'lang_68', 'description_68', 'lang_69', 'description_69', 'lang_70', 'description_70']

table_translation = 'countries.city_translated'

import psycopg2
import re

conn = psycopg2.connect(database="countries", host='localhost', user="postgres", password="Password")
cur = conn.cursor()
new_cursor = conn.cursor()

cur.execute("""SELECT id FROM %s """ % initial_table)
rows = cur.fetchall()
print("%i rows retrieved" % cur.rowcount)

new_cursor.execute("""BEGIN""")

for row in rows:
    print('row:', row)
    get_id = row[0]
    cur.execute("""SELECT %s FROM %s WHERE id=%s """ % (",".join(init_table_columns), initial_table, get_id))
    row_w_info = cur.fetchall()
    for i in range(140):
        if i%2==0:
            name = row_w_info[0][i]
            description = row_w_info[0][i+1]

            lang_text = init_table_columns[i]
            lang_id = int(re.findall(r'\d+', lang_text)[0])

            # There are 70 translations, but there is no info what languages are 68, 69, 70
            if lang_id >= 68:
                lang_id = None

            new_cursor.execute("INSERT INTO countries.city_translated (city_id, name, description, lang_id) VALUES (%s, %s, %s, %s)", (get_id, name, description, lang_id))

new_cursor.execute("""COMMIT""")

cur.close()
new_cursor.close()
conn.close()