英文:
Why can I not query table in Oracle from Python but I can from SQL Developer
问题
代码中的错误提示是:"DatabaseError: (cx_Oracle.DatabaseError) ORA-00942: table or view does not exist"
我在 SQL Developer 中查询所有表格都没问题,但在 Python 中使用 sqlalchemy 查询某些表时遇到了这个错误。我在 SQL Developer 和 Python 中使用相同的凭据连接。以下是我的代码:
df = pd.read_sql_query('SELECT * FROM my_schema.my_table', engine)
在 SQL Developer 中运行相同的查询如下:
SELECT * FROM "my_schema"."my_table";
这在 SQL Developer 中可以正常工作。再次强调,Python 部分对除了我实际需要的表之外的任何其他表都有效。这是为什么?是我的用户权限问题还是我在安装 Oracle Instant Client 时出错了?
英文:
As per the title. I can query all tables in SQL Developer, but for some of them I run into this error in Python with sqlalchemy:
"DatabaseError: (cx_Oracle.DatabaseError) ORA-00942: table or view does not exist"
I am using the same credentials to connect in SQL Developer and Python. This is my code:
df = pd.read_sql_query('SELECT * FROM my_schema.my_table', engine)
When I run the same query in SQL Developer like so:
SELECT * FROM "my_schema"."my_table";
it works. Again, the Python stuff works with any other table except the one that I actually need...How can this be? Is it my user permissions or did I do something wrong with my Oracle Instant Client installation?
答案1
得分: 2
在SQL中,你可以使用带引号和不带引号的标识符。
- 带引号的标识符是
"my_schema"."my_table"
,区分大小写。 - 不带引号的标识符是
my_schema.my_table
,实际上不区分大小写(SQL引擎会隐式地将所有不带引号的标识符转换为大写,因此与"MY_SCHEMA"."MY_TABLE"
相同)。
在一个查询中,你使用了带引号的小写标识符,而在另一个查询中使用了不带引号的(实际上是大写的)标识符,因此在标识符不匹配时找不到表。
由于你用小写标识符构建了模式和表,所以必须在引用它们时使用带引号的标识符。这意味着你的Python代码应该与SQL Developer中有效的查询具有相同的带引号标识符:
df = pd.read_sql_query('SELECT * FROM "my_schema"."my_table"', engine)
更好的做法是在构建模式和表时使用不带引号的标识符(或大写标识符),以便不带引号的标识符能够正常工作,但现在已经完成了,所以你要么重新创建模式和表,要么始终使用带引号的标识符。
英文:
In SQL you can use quoted and unquoted identifiers.
- Quoted identifiers are
"my_schema"."my_table"
and are case-sensitive. - Unquoted identifiers are
my_schema.my_table
and are effectively case-insenstive (and the SQL engine will implictly convert all unquoted identifers to upper-case so would be the same as"MY_SCHEMA"."MY_TABLE"
).
You are using quoted lower-case identifiers in one query and unquoted (effectively upper-case) identifiers in the other query and, hence, it is not finding the table when the identifiers do not match.
Since you have built the schema and the table with lower-case identifiers then you MUST use quoted identifiers whenever you refer to them. Which means your python code should have exactly the same query as the working one from SQL Developer, with the quoted identifiers:
df = pd.read_sql_query('SELECT * FROM "my_schema"."my_table"', engine)
Better practice would have been to use unquoted identifiers (or upper-case identifiers) when you built the schema and table so that unquoted identifiers would work, but its done now so you either have to recreate the schema and tables or always use quoted identifiers.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论