Python psycopg2设置约束可延迟

时间:2015-04-21 15:46:27

标签: python postgresql psycopg2

我有下面的类来处理我的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

`

1 个答案:

答案 0 :(得分:0)

我自己想通了。显然psycopg2的行为方式是因为我在__init__之外声明了连接和类变量。