我有下面的类来处理我的Postgres数据库,我遇到了涉及外键的多个插入问题。如果我先在父表中插入然后在子表中插入,我会收到外键冲突错误,尽管我认为我已经有了所有可延迟的东西。 (未启用自动提交)
对外键的约束设置如下:
CONSTRAINT tblorganisations_status_tblorganisations_fkey FOREIGN KEY (org_id)
REFERENCES organisations.tblorganisations (org_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY IMMEDIATE;
调用该类的代码:
postgres = Postgresql("organisations")
r = postgres.insert(self.db_table, data, return_cols='org_id')
self.org_id = r['org_id']
postgres.insert('tblorganisations_status',
{'org_id': self.org_id,
'org_status_id': 'NEW_CGM'})
postgres.commit()
上课:
class Postgresql():
conn = None
cur = None
last_result = None
def __init__(self, schema=None):
reload(sys) # Reload does the trick!
sys.setdefaultencoding("utf-8")
self.log = Log()
self.connect()
if schema is not None:
self.schema = schema
self.set_default_schema(schema)
def connection_string(self):
return 'host=%s port=%s dbname=%s user=%s password=%s' % \
(get_config('DATABASE', 'host'),
get_config('DATABASE', 'port'),
get_config('DATABASE', 'dbname'),
get_config('DATABASE', 'user'),
get_config('DATABASE', 'password'))
def connect(self):
try:
self.conn = psycopg2.connect(self.connection_string())
self.conn.set_session(isolation_level='read uncommitted', deferrable=True)
self.cur = self.conn.cursor(cursor_factory=RealDictCursor)
except Exception, e:
self.log.error(e.message)
raise
def set_default_schema(self, schema):
try:
self.cur.execute("SET search_path TO %s,public;", (schema, ))
except Exception, e:
self.log.error(e.message)
raise
def commit(self):
self.conn.commit()
self.close()
def rollback(self):
self.conn.rollback()
self.close()
def close(self):
self.cur.close()
self.conn.close()
def insert(self, table, data, return_cols=None, **kwargs):
data = self.cleanup_data(table, data)
fields = data.keys()
if self.schema is not None:
table = self.schema + '.' + table
sql = "INSERT INTO " + table + " ("
sql += ",".join(fields) + ") VALUES (" + ",".join(["%s"]*len(fields)) + ")"
if return_cols:
sql += " RETURNING " + return_cols
sql += ";"
if 'debug' in kwargs:
raise Exception(sql % tuple(data.values()))
try:
self.log.event('POSTGRES: ' + (sql % tuple(data.values())))
self.cur.execute(sql, data.values())
if return_cols:
result = self.cur.fetchone()
return result
except Exception, e:
self.log.error(e.message)
self.conn.rollback()
self.close()
raise
`
答案 0 :(得分:0)
我自己想通了。显然psycopg2的行为方式是因为我在__init__
之外声明了连接和类变量。