通过cx_Oracle和sqlalchemy设置`client_identifier`

时间:2018-02-10 18:10:24

标签: python flask sqlalchemy cx-oracle

我正在Flask,sqlalchemy和cx_Oracle上运行flask-rest-jsonapi应用程序。此项目的一个要求是,通过cx_Oracle(relevant documentation)提供的连接属性client_identifier可以根据JWT中发送的每个客户端请求的值进行修改。我们需要能够写入此属性,因为我们的内部审计表使用它来跟踪各个用户所做的更改。

在PHP中,setting this value is straightforward使用oci8,并且在过去对我们有用。

但是,我一直无法弄清楚如何使用这个新的应用程序结构设置相同的属性。在cx_Oracle中,client_identifier属性是“只写”属性,因此很难在不进入后端并检查数据库会话属性的情况下验证是否正确设置了该值。您可以通过sqlalchemy raw_connection对象访问此属性。

除了难以阅读之外,设置该值无效。我们从每个请求传入的JWT中获取所需的客户端标识符值,并尝试在原始连接对象上设置它。虽然设置值的操作不会引发错误,但该值不会显示在相关会话的后端,即在数据库端查看会话时client_identifier属性为空。

from flask import Flask, jsonify, request
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

db = SQLAlchemy(app)

# the client_identifier property is available at db.engine.raw_connection()

# attempt to set the client_identifier property
raw_conn = db.engine.raw_connection()
raw_conn.client_identifier = 'USER_210'

# execute some sql using raw_conn.cursor()...
# the client identifier value on the db side for this request is null

上面显示的方法是否设置client_identifier的正确方法?如果是,那么在使用USER_210视图查询后端会话表时,为什么client_identifier列中未列出v$session

1 个答案:

答案 0 :(得分:0)

在纯cx_Oracle中,这对我有用:

import cx_Oracle

db = cx_Oracle.connect("system", "oracle", "localhost/orclpdb")
db.client_identifier = 'this-is-me'
cursor = db.cursor()
cursor.execute("select username, client_identifier from v$session where username = 'SYSTEM'")
v = cursor.fetchone()
print(v)

结果是:

$ python3 q1.py 
('SYSTEM', 'this-is-me')

我没有设置测试您的确切方案。