2016-09-15 65 views
1

下不起作用:Django update()交換MySQL中兩個字段的值?

Car.objects.filters(<filter>).update(x=F('y'), y=F('x')) 

既是xy最終是相同的值。

由於性能(大型記錄集),我需要使用update()而不是save()。

是否有任何其他方式進行類似上面的更新以模仿Python的x, y = y, x

db是MySQL,which might explain why the resulting SQL statement doesn't work

+1

這是SQL行爲的方式。例如'UPDATE myapp_car set x = y,y = x'會將它們都設置爲y – e4c5

+1

@ e4c5不,它不會。這只是** MySQL **被破壞了,也許這就是你和Tomas正在使用的。 –

+1

那麼,我確實有三個RDBMS,但不幸的是,我對這個只有一個mysql,應該也試過postgresql @AnttiHaapala – e4c5

回答

4

如果您使用的是正確的符合標準的SQL數據庫,這應該可以正常工作。查詢將擴大到

UPDATE car SET x = y, y = x WHERE <filter> 

這將至少在PostgreSQL(下文)正常工作,sqlite3的(如下圖),OracleMSSQL,但MySQL的實現是壞了。

的PostgreSQL:

select * from car; 
    x | y 
---------+------ 
prefect | ford 
(1 row) 

test=> update car set x = y, y = x; 
UPDATE 1 
test=> select * from car; 
    x | y  
------+--------- 
ford | prefect 
(1 row) 

的SQLite3

sqlite> select * from foo; 
prefect|ford 
sqlite> update foo set x = y, y = x; 
sqlite> select * from foo; 
ford|prefect 

然而,MySQL的違反SQL標準,

mysql> insert into car values ('prefect', 'ford'); 
Query OK, 1 row affected (0.01 sec) 

mysql> select * from car; 
+---------+------+ 
| x  | y | 
+---------+------+ 
| prefect | ford | 
+---------+------+ 
1 row in set (0.00 sec) 

mysql> update car set x = y, y = x; 
Query OK, 1 row affected (0.00 sec) 
Rows matched: 1 Changed: 1 Warnings: 0 

mysql> select * from car; 
+------+------+ 
| x | y | 
+------+------+ 
| ford | ford | 
+------+------+ 
1 row in set (0.00 sec) 

因此,有一個可移植的方式來做到這一點使用符合標準的, SQL數據庫,但MySQL不是其中之一。如果您不能使用for ... save循環,那麼您必須使用Swapping column vales in MySQL中的一些黑客;臨時變量似乎是最通用的變量;儘管我不確定是否可以使用Django的F構造的臨時變量。

-1

我不認爲更新可以做到這一點,因爲它基本上是一個SQL包裝。 儘管如此,你可以使用save(values = ['x','y'])。希望它不會那麼慢。 或者,您可以使用django的原始sql執行交換(請參閱Swap values for two rows in the same table in SQL Server