Acredito que instruções parametrizadas como esta devem ser usadas com valores e não nomes de tabelas (ou palavras-chave SQL, etc.). Então você está basicamente sem sorte com isso.
No entanto, não se preocupe, pois esse mecanismo destina-se a impedir a injeção de SQL e você normalmente sabe qual tabela deseja acessar no momento da gravação do código, portanto, há pouca chance de alguém injetar código malicioso. Apenas vá em frente e escreva a tabela na string.
Se, por algum motivo (possivelmente perverso) você mantiver o nome da tabela paramétrico assim:
- Se o nome da tabela vier do seu programa (por exemplo, um dicionário ou atributo de classe), faça a substituição de string normal.
- Se o nome da tabela vier do mundo externo (pense em "entrada do usuário"):não faça isso ou confie completamente no usuário e aplique a abordagem anterior 1.
Por exemplo:
cursor.execute(
'SELECT * FROM %s where %s = %s'
% ("my_table", "colum_name", "%s"), #1
("'some;perverse'string;--drop table foobar")) #2
#1
:Deixe o terceiro %s ser substituído por outro '%s' neste momento, para permitir o processamento posterior por psycopg2#2
:Esta é a string que será corretamente citada por psycopg2 e colocada em vez do terceiro '%s' na string original