2016-09-15 13 views
1

次は動作しません:MySQLの2つのフィールドの値を交換するDjango update()?

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

xyの両方が同じ値で終わるよう。

パフォーマンス(大量のレコード)のためにsave()の代わりにupdate()を使用する必要があります。

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

さて、私は3つの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はその1つではありません。 for ... ループを使用できない場合は、Swapping column vales in MySQLからいくつかのハックに頼る必要があります。一時変数は最も一般的な変数のようです。私はあなたがDjangoのF構造体で一時変数を使用できるかどうかはわかりませんが。

-1

私はそれが基本的にSQLラッパーであるので、更新ができないと思います。 あなたができることは、use save(values = ['x'、 'y'])です。うまくいけば、それは遅くなることはありません。 また、djangoのraw sqlを使用してスワップを実行することもできます(Swap values for two rows in the same table in SQL Serverを参照)

関連する問題