【问题标题】:Inserting into PostgreSQL database without knowing the number of variables, in python在不知道变量数量的情况下,在 python 中插入 PostgreSQL 数据库
【发布时间】:2017-03-09 13:37:35
【问题描述】:

基本上,我使用 python 库来查询单词的同义词,然后将该单词及其同义词添加到 postgreSQL 表中。如果某些表列是空的,那很好,但我不知道如何将同义词插入数据库,因为我不知道会有多少。

例如,我有一个 6 列的表,1 表示原始单词,5 表示其同义词。对于一个词,我可能会得到 3 个同义词,但对于其他词,我可能会得到全部 5 个。

我设法编写此任务的唯一方法是一组可怕的 if 语句:

for word in textlist:
syns = dictionary.synonym(word)
num = len(syns)

if len(syns) == 5:
    for i in syns:
        syn1 = i[0]
        syn2 = i[1]
        syn3 = i[2]
        syn4 = i[3]
        syn5 = i[4]

等等...然后使用这些变量将同义词插入到数据库表中。

我想到的一种方法是构建另一个单词和同义词列表,然后循环遍历以添加到表格中。但我不知道该怎么做。关于如何进一步推动的任何帮助将是一个很大的帮助。谢谢。

注意:syns 返回一个列表对象。

编辑:

感谢@systemjack,我已将系统更改为有 3 个表格列。 id(这是一个串行主键)、word 和 synos(最初是 syn,但为了确保它不是一些奇怪的关键字而进行了更改)。每个单词应该与一个同义词一起添加到一行中,然后下一行可以是具有不同同义词的同一个单词,依此类推……无论如何,新方法如下:

for word in textlist:
    syns = dictionary.synonym(word)
    if syns is not None:
        for syn in syns:
            cursor.execute('INSERT INTO wordsyn (word, "synos") VALUES (%s, %s);', (word, syn))

我现在得到了错误 psycopg2.ProgrammingError: column "synos" of relation "wordsyn" does not exist LINE 1: INSERT INTO wordsyn (word, "synos") VALUES ('&c

我在 synos 周围加上了双引号,试图让它工作,但没有它们也无法工作。任何进一步的帮助将不胜感激。

\d+ wordsyn 输出:

最终编辑:发现问题。没有正确的数据库中的表。我以为 \dt 只显示了您当前数据库中的表,但显然没有。

【问题讨论】:

  • 如果可以更改您的数据库结构,那么我们可以轻松找到合适的解决方案。这是一个选择吗?
  • @gipsy 可以。我没有以任何方式特别绘制出来。但这在某种程度上取决于您的建议。
  • 如果您为结果表提供一个示例用例,这将有助于找出最佳架构。
  • 如果你使用 psql 你会添加\d+ wordsyn的输出吗?
  • 我很难过。一切对我来说都是正确的。使用 psql 手动插入是否有效?喜欢:insert into wordsyn (word, synos) values ('foo', 'bar');

标签: python database postgresql


【解决方案1】:

典型的关系方法会将其设置为一个包含单词列和第二个同义词列的两列表。然后,每个单词-同义词组合都有一行。

在这种情况下,您使用数据的查询要简单得多。您真的不想处理可变数量的填充列。另外,如果一个词有 6 个同义词会怎样?

最简单的实现需要每个单词多次插入,但这没什么大不了的。还有ways to batch up the inserts

如果您真的希望每个单词有一行,您可以使用SPLIT_PARTSTRING_AGG 的组合在一列中存储可变数量的值。不过,我强烈建议使用前一种方法。

您还可以管理更复杂的动态structures as JSON

请记住,最后两种方法都会慢得多。

使用第一种方法,您的插入将类似于:

for word in textlist:
    syns = dictionary.synonym(word)
    for syn in syns:
        cursor.execute('insert into syns (word, syn) values (%s, %s);', (word, syn))

然后,如果您想查看某个单词的所有同义词,您可以执行以下操作:

select word, string_agg(syn, ', ') 
from syns where word='perspicuitous'
group by word;

【讨论】:

  • 我想你说 col1 是单词,col2 是该单词的同义词,一个单词需要多行。但是 col1 不能是主键。
  • 是的。已更正。谢谢。
  • @systemjack 感谢您的回复。这看起来会很好用。试用后我会回复您。
  • @systemjack 好的,所以我认为这会起作用。我创建了一个包含 3 列的表(称为 wordsyn),一列是自动生成的 id(我稍后会需要它)另外两列如您所说,一列用于单词 - 称为单词 - 另一列用于同义词- 称为同步。我的代码遵循您的示例,但我收到错误 psycopg2.ProgrammingError: column "syn" of relation "wordsyn" does not exist 我不确定这可能是什么,因为这绝对是列的名称。
  • 如果你这样做select word, "syn" from wordsyn limit 1;,它有效吗?如果没有,请尝试 select * from wordsyn limit 1; 并查看标题是什么。
【解决方案2】:

一种方法是创建 2 个表,一个用于单词,另一个用于同义词,如下所示

Word:

id  - primary key - could be autogenerated.
word - sring - To store the word

Synoym:

id -- primary key - could be autogenerated.
word_id --  Foreign key to Word table id
synonym --  String - The synonym 

对于每个单词,如果单词存在,则在 Word 表中查找,如果不插入,则只获取现有条目的 id。 使用 dictionary.synonym(word) 获取单词的同义词。对于每个同义词,从上面查找带有单词 id 的同义词表和同义词,如果不存在则插入,否则继续下一个同义词。

对所有单词重复此操作。

为一个词选择同义词变成如下查询:

select syn.synonym from synonym syn , word wd 
where wd.id = syn.word_id and wd.word = 'foo'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-12
    • 1970-01-01
    相关资源
    最近更新 更多