2

リスト/セット/タプルを(psycopg2を介して)pythonからpostgresクエリに1列のテーブルとして渡す方法を知りたいです。たとえば、リストがの場合['Alice', 'Bob']、テーブルは次のようになります。

| Temp  |
+-------+
| Alice |
| Bob   |

以下のセクションを読んだ後、誰かが私の結果を達成するための代替案を持っているなら、それも問題ありません。

バックグラウンド

関心のある3つの列を持つSQLテーブルがあります。

ID | Members | Group
---+---------+----------
1  | Alice   | 1
2  | Alice   | 1
3  | Bob     | 1
4  | Charlie | 1
5  | Alice   | 2
6  | Bob     | 2
7  | Alice   | 3
8  | Bob     | 4
9  | Charlie | 3

メンバーの特定の組み合わせを持つグループのテーブルが必要です。メンバーは、グループ内に複数のアイテムを持つ場合があることに注意してください(ID 1および2など)。

以下のように、['Alice']彼女がどのグループに属し(現在)、どのグループに彼女だけが含まれている(一意)かを入力します。

Group | Type
------+--------
1     | present
2     | present
3     | present

の入力の場合['Alice', 'Bob']

Group | Type
------+--------
1     | present
2     | unique

読んでみると、ここで説明されているように関係分割を探しているように見えます。入力はPythonで処理されたWebフォームから取得されるため、元の質問が尋ねる内容を実行する必要があります。繰り返しになりますが、代替ソリューションも歓迎します。

4

1 に答える 1

3

メンバーカウントを作成するサブクエリを作成してから、GROUP BYステートメントを使用して単純な除数クエリを実行する必要がありますがIN static_set、別のテーブルではなく句に対して実行します。これはPythonであるため、静的セットのサイズはすでにわかっています。

すでにデータベースカーソルがあり、テーブルの名前は次のとおりですGroupMembers

MEMBERSHIP_QUERY = '''
    SELECT gm.group, mc.memberscount = %(len)s AS type
      FROM groupmembers gm
      JOIN (SELECT "group", COUNT(DISTINCT members) as memberscount 
              FROM groupmembers
             GROUP BY "group") mc
      ON gm.group = mc.group
    WHERE gm.members IN %(set)s
    GROUP BY gm.group, mc.memberscount
    HAVING COUNT(DISTINCT gm.members) = %(len)s;
'''

def membership(members):
    # obtain a cursor
    for row in cursor.execute(MEMBERSHIP_QUERY, dict(len=len(members), set=members)):
        yield dict(group=row[0], type=row[1])

したがって、このクエリを実行するためにTEMPテーブルを使用する必要はありません。

他の目的でTEMPテーブルが必要な場合は、行のセットを挿入するのが最も簡単.executemany()です。

members = ['Alice', 'Bob']
cursor.execute('CREATE TEMP TABLE tmp_members (member CHAR(255)) ON COMMIT DROP;')
cursor.executemany('INSERT INTO tmp_members VALUES (%s);',
    [(name,) for name in members])

.executemany()シーケンスのシーケンスを期待していることに注意してください。各エントリは一連の行データであり、この場合はそれぞれ1つの名前しか保持しません。テーブルを埋めるために、単一アイテムのタプルのリストを生成します。

%(name)sまたは、一連のマッピングを使用してパラメーター構文を使用することもできます(したがって、行データシーケンスはになります[dict(name=name) for name in members])。

于 2012-08-20T16:39:27.083 に答える