Python cx_Oracle模块:无法在代码中格式化查询

Python cx_Oracle模块:无法在代码中格式化查询,python,oracle,boto3,cx-oracle,Python,Oracle,Boto3,Cx Oracle,我正在使用cx_Oracle模块连接到Oracle数据库。在脚本中,我使用了两个变量schema_name和table_name。下面的查询工作正常 cur1.execute("select owner,table_name from dba_tables where owner ='schema_name'") 但是我需要查询表的行数,其中我需要用schema\u名称限定表的名称,因此查询应该是 从schema_name.table_name中选择count* 当在代码中

我正在使用cx_Oracle模块连接到Oracle数据库。在脚本中,我使用了两个变量schema_name和table_name。下面的查询工作正常

cur1.execute("select owner,table_name from dba_tables where owner ='schema_name'")
但是我需要查询表的行数,其中我需要用schema\u名称限定表的名称,因此查询应该是

从schema_name.table_name中选择count*

当在代码中使用时,这不起作用,我尝试将其放在三引号、单引号和其他选项中,但它没有按预期格式化查询,因此不存在与表相关的错误


非常感谢您的指导。

在这种情况下,您也可以尝试设置连接。当前的\u架构,请参阅

例如,如果您在自己的架构中创建表:

SQL> show user
USER is "CJ"
SQL> create table ffff (mycol number);

Table created.

SQL> insert into ffff values (1);

1 row created.

SQL> commit;

Commit complete.
然后运行作为不同用户连接的Python代码:

import cx_Oracle
import os

import sys, os
if sys.platform.startswith("darwin"):
    cx_Oracle.init_oracle_client(lib_dir=os.environ.get("HOME")+"/Downloads/instantclient_19_8")

username = "system"
password = "oracle"
connect_string = "localhost/orclpdb1"

connection = cx_Oracle.connect(username, password, connect_string)

connection.current_schema = 'CJ';

with connection.cursor() as cursor:
    sql = """select * from ffff"""
    for r in cursor.execute(sql):
        print(r)

    sql = """select sys_context('USERENV','CURRENT_USER') from dual"""
    for r in cursor.execute(sql):
        print(r)
输出将是:

(1,)
('SYSTEM',)

最后一个查询显示被更改的不是用户,而是第一个查询自动从“ffff”更改为“CJ.ffff”。

可能会使用一个包含占位符的预处理语句,占位符的形式为…{}.{}.formatsc,tb

sc='myschema'
tb='mytable'

cur1.execute("SELECT COUNT(*) FROM {}.{}".format(sc,tb))
print(cur1.fetchone()[0])

很好的解决方案。但我在这里对术语提出质疑:“绑定变量”的使用并不是Oracle对绑定变量的定义。Oracle的绑定变量是将数据与代码分开的一种方法。使用此代码段,根据已知的“安全”列表验证sc&tb值仍然很重要。感谢@ChristopherJones您是对的,修复了解释。您也可以使用f字符串,如cur1.executefselect count*from{sc}.{tb}-但如前所述,您需要确保sc和tb的值已知或已验证。感谢Christopher,我尝试在我的代码中使用它,但我发现即使在将模式设置为我想要的模式后,当我尝试查询模式中存在的表时,它表示该表不存在,并且当我尝试查询当前用户时,它显示admin,这是与之建立db连接的用户,而不是正在使用connection.current\u schema设置的用户。“schema\u name='myschemaname'表\u name='mypassword'dsn\u tns1=cx\u Oracle.makedsndb\u主机,db\u端口,db\u name conn1=cx\u Oracle.connectuser=username,password=password,dsn=dsn\u tns1 cur1=conn1.cursor conn1.current\u schema=schema\u name cur1.executeSELECT COUNT*FROM{}.formattable\u name printcur1.fetchall cur1.executeSELECT sys\u context'USERENV','current\u USER'FROM dual``我用一个例子更新了答案。谢谢Christopher,出于测试目的,我在schema test中创建了一个表测试,它运行良好。但当我查询名称中带有下划线的实际表时,代码失败。我假设这与表名必须在双引号中有关。即使在sqlplus中,当我从test.test查询select*表时,它也可以正常工作,但当我从scheme.table\u name查询select*时,它失败了,我必须用双引号指定table\u name