Python 在另一个表中插入外键,并在PostgreSQL中插入executemany()

Python 在另一个表中插入外键,并在PostgreSQL中插入executemany(),python,postgresql,insert,foreign-keys,executemany,Python,Postgresql,Insert,Foreign Keys,Executemany,我尝试将语句表中代码列的行值作为公司表中的外键插入。我采取了以下步骤: 创建表 cur.execute("CREATE TABLE IF NOT EXISTS companies (code INT NOT NULL PRIMARY KEY, short_name VARCHAR(255) NOT NULL, long_name VARCHAR(255) NOT NULL)") cur.execute("CREATE TABLE IF NOT EXISTS statements (statem

我尝试将语句表中代码列的行值作为公司表中的外键插入。我采取了以下步骤:

创建表

cur.execute("CREATE TABLE IF NOT EXISTS companies (code INT NOT NULL PRIMARY KEY, short_name VARCHAR(255) NOT NULL, long_name VARCHAR(255) NOT NULL)")

cur.execute("CREATE TABLE IF NOT EXISTS statements (statement_id SERIAL NOT NULL PRIMARY KEY, statement_name VARCHAR(255) NOT NULL, code INT NOT NULL, FOREIGN KEY (code) REFERENCES companies_list (code))")
公司表中包含的代码列(即)

下一步是将所需数据插入到语句表中,如下所示:

statement_name = ["balance_sheet", "income_statement", "cash_flow"]

code = "SELECT code FROM companies_list WHERE code IS NOT NULL"

statements = [tuple((t,)) for t in zip(statement_name, code)]

query = "INSERT INTO statements (statement_name, code) VALUES %s"
cur.executemany(query, statements)
我得到了以下错误:

psycopg2.DataError: invalid input syntax for integer: "S"
LINE 1: ...ents (statement_name, code) VALUES ('balance_sheet', 'S')
我想得到的最终结果如下:

statement_id |   statement_name    |   code
---------------------------------------------
     1           balance_sheet         113
     2           income_statement      113
     3           cash_flow             113
     4           balance_sheet         221
     5          income_statement       221
     6           cash_flow             221

错误源于此行:

code = "SELECT code FROM companies_list WHERE code IS NOT NULL"
这不会执行实际的查询,而是将SQL select语句字符串分配给
code
变量。然后,下一行用
code
压缩语句名,因为
code
是一个字符串(一个iterable),所以
code
的前3个字符与
语句名
中的项目压缩,结果是:

[(('balance_sheet', 'S'),), (('income_statement', 'E'),), (('cash_flow', 'L'),)]
这就是
's'
的来源-它是
code
字符串中“SELECT”的第一个字符
'S'
是一个字符串,而不是
语句
表架构中定义的整数,因此出现错误

您可以看到使用
cursor.mogrify()
生成的查询:


解决此问题的一种方法是执行
code
中包含的查询以获取公司代码列表,然后使用该列表构造
INSERT
查询:

import itertools

cur.execute("SELECT code FROM companies_list WHERE code IS NOT NULL")
codes = [row[0] for row in cur.fetchall()]
query = 'INSERT INTO statements (statement_name, code) VALUES (%s, %s)'
args = itertools.product(statement_name, codes)
cur.executemany(query, args)

此处用于形成语句名称和公司代码的笛卡尔乘积。这是模仿数据库连接功能,因此,如果您的数据库中有语句类型,那么使用SQL而不是Python可能会更好。

my bad我一般不熟悉数据库,我认为在使用查询内部代码之前,我在ExecuteMay中成功地使用了查询。。那么现在如果这不起作用,我该如何解决这个问题。。最后一个表(语句)中所需的结果)…@T.M:您需要执行查询,或者以其他方式获取公司代码列表。请参阅更新的答案。我尝试了您的代码,但遇到了一个错误('NoneType'对象没有'fetchall'属性)。。然后将其更改为“symbols=cur.execute”(“从公司列表中选择符号,符号不为空”)symbols=cur.fetchall(),并针对
psycopg2
cursorsor.execute()返回
None
,面对另一个erorr(cur.executemany(query,args)TypeError:NOT所有在字符串格式化过程中转换的参数),因此出现了错误。我已经更新了代码来处理这个问题。
>>> statement_name = ["balance_sheet", "income_statement", "cash_flow"]
>>> code = "SELECT code FROM companies_list WHERE code IS NOT NULL"
>>> statements = [tuple((t,)) for t in zip(statement_name, code)]
>>> query = "INSERT INTO statements (statement_name, code) VALUES %s"
>>> for args in statements:
...     print(cur.mogrify(query, args))
... 
INSERT INTO statements (statement_name, code) VALUES ('balance_sheet', 'S')
INSERT INTO statements (statement_name, code) VALUES ('income_statement', 'E')
INSERT INTO statements (statement_name, code) VALUES ('cash_flow', 'L')
import itertools

cur.execute("SELECT code FROM companies_list WHERE code IS NOT NULL")
codes = [row[0] for row in cur.fetchall()]
query = 'INSERT INTO statements (statement_name, code) VALUES (%s, %s)'
args = itertools.product(statement_name, codes)
cur.executemany(query, args)