Psycopg2 不喜欢以小写字母开头的表名
我在Windows XP上运行ActiveState的ActivePython 2.6.5.12和PostgreSQL 9.0 Beta 1。
当我创建一个表名首字母大写(比如说Books)时,使用psycopg2执行查询语句execute("SELECT * FROM Books")
时,会出现“编程错误:关系"books"不存在”的错误信息。如果我执行execute("SELECT * FROM books")
,也会出现同样的错误。不过,如果我把表名改成首字母小写(比如说books),那么上面的任意一个查询语句都能正常工作。
表名是不是应该首字母小写?这是一个设置、特性还是bug?我是不是漏掉了什么明显的东西?
3 个回答
4
我经常需要使用Psycopg2来处理一些别人创建的表,这些表的列名有很多大小写混合的情况。
我找到的解决办法是使用
from psycopg2.extensions import AsIs
然后把列名放到一个变量里,比如:
column_name = '"Column_Mixed_Case"'#Mind the '" quotes combination !
接着把这个变量传递给SQL,像这样:
data = AsIs(column_name)
sql = "select %s from table"
cur.execute(sql,data)
11
补充一下其他回答,PostgreSQL在处理标识符(比如表名和列名)时的大小写敏感性行为是这样的:
- 如果名字没有加引号,它会被转换成小写。如果加了引号,就不会改变。
- 然后,会尝试进行大小写敏感的匹配。
这个规则不仅适用于查询,也适用于模式操作,特别是创建表的时候。
如果你想写可移植的应用程序,建议你要么总是加引号,要么从不加引号。
出现的问题,可能是因为在创建表和列的时候加了引号(所以它们没有被转换成小写)。因此,现在在所有查询中都必须加引号(并且要区分大小写)。
通常情况下,一切都按预期工作。
db=# create table Xxx (id integer); -- unquoted, will be converted to lowercase
CREATE TABLE
db=# select * from xXx; -- this works ok
id
----
(0 rows)
db=# create table "Xxxx" (id integer); -- will be left untouched
CREATE TABLE
db=# select * from xxxx; -- bad
ERROR: relation "xxxx" does not exist
LINE 1: select * from xxxx;
db=# select * from Xxxx; -- bad
ERROR: relation "xxxx" does not exist
LINE 1: select * from Xxxx;
^
db=# select * from "Xxxx"; -- ok
id
----
(0 rows)
db=# \dt *xx*
List of relations
Schema | Name | Type | Owner
--------+------+-------+----------
public | Xxxx | table | postgres
public | xxx | table | postgres
9
请阅读“标识符和关键字”这部分手册,特别是关于“带引号的标识符”的内容。