2010-04-14 45 views
2

這是我的第一個問題接受作爲參數的文本字符串時,奇怪的行爲。的Django +南+的Python:使用功能

我試圖執行在Django一個SQL查詢(向南遷移):

from django.db import connection 
# ... 
class Migration(SchemaMigration): 
    # ... 
    def transform_id_to_pk(self, table): 
     try: 
      db.delete_primary_key(table) 
     except: 
      pass 
     finally: 
      cursor = connection.cursor() 

      # This does not work 
      cursor.execute('SELECT MAX("id") FROM "%s"', [table]) 

      # I don't know if this works. 
      try: 
       minvalue = cursor.fetchone()[0] 
      except: 
       minvalue = 1 
      seq_name = table + '_id_seq' 

      db.execute('CREATE SEQUENCE "%s" START WITH %s OWNED BY "%s"."id"', [seq_name, minvalue, table]) 
      db.execute('ALTER TABLE "%s" ALTER COLUMN id SET DEFAULT nextval("%s")', [table, seq_name + '::regclass']) 
      db.create_primary_key(table, ['id']) 
    # ... 

我用這個函數是這樣的:

self.transform_id_to_pk('my_table_name') 

所以應該:

  1. 找到的最大的存在ID或0(崩潰)
  2. 創建序列南Ë
  3. 創建序列
  4. 更新的ID字段使用序列
  5. 更新ID作爲PK

但它崩潰和錯誤說:

File "../apps/accounting/migrations/0003_setup_tables.py", line 45, in forwards 
    self.delegation_table_setup(orm) 
    File "../apps/accounting/migrations/0003_setup_tables.py", line 478, in delegation_table_setup 
    self.transform_id_to_pk('accounting_delegation') 
    File "../apps/accounting/migrations/0003_setup_tables.py", line 20, in transform_id_to_pk 
    cursor.execute(u'SELECT MAX("id") FROM "%s"', [table.encode('utf-8')]) 
    File "/Library/Python/2.6/site-packages/django/db/backends/util.py", line 19, in execute 
    return self.cursor.execute(sql, params) 
psycopg2.ProgrammingError: relation "E'accounting_delegation'" does not exist 
LINE 1: SELECT MAX("id") FROM "E'accounting_delegation'" 
          ^

我已經縮短了文件路徑以方便使用。

是什麼 「E'accounting_delegation'」 是什麼意思?我怎麼能擺脫它?

謝謝!

卡洛斯。

+0

我不得不說我是新來的python,django,南... – carlosescri 2010-04-14 11:18:26

回答

4

的問題是,你正在使用DB-API參數的事情是不是SQL數據。當你做這樣的事情:

cursor.execute('INSERT INTO table_foo VALUES (%s, %s)', (col1, col2)) 

的DB-API模塊(Django的爲你使用任何數據庫,在這種情況下,前端)會知道適當地逃脫「COL1」和「COL2」的內容,並取代%s與他們在一起。請注意,%s的周圍沒有引號。但是,這僅適用於SQL 數據,而不是SQL ,如表名和序列的名字,因爲他們需要(或者根本沒有。)當你做

cursor.execute('INSERT INTO "%s" VALUES (%s, %s)', (tablename, col1, col2)) 

在以不同的方式引用表名被引述,如果你的意思是它是字符串數據插入,和你結束了,例如「‘table_foo’」。您需要將SQL元數據,這是查詢的一部分,你的SQL數據,這是不是,分開就像這樣:

sql = 'INSERT INTO TABLE "%s" VALUES (%%s, %%s)' % (tablename,) 
cursor.execute(sql, (col1, col2)) 

注意,因爲Django的DB-API前端的paramstyle是「pyformat」(它使用%s作爲佔位符),當您執行字符串格式化來創建要執行的SQL時,您需要將其轉義。並且請注意,當您從不安全的源獲取表名並且不驗證它時,這對於SQL注入攻擊是不安全的。

+0

謝謝你的教訓,我學到了很多東西。 – carlosescri 2010-04-14 11:58:38