以下不起作用:
Car.objects.filters(<filter>).update(x=F('y'), y=F('x'))
因为x
和y
最终都是相同的值。
由于性能(大量记录集),我需要使用update()而不是save()。
还有其他方法可以像上面那样模仿Python x, y = y, x
进行更新吗?
db是MySQL,which might explain why the resulting SQL statement doesn't work。
答案 0 :(得分:5)
如果您使用正确的符合标准的SQL数据库,这应该可以正常工作。查询将扩展为
UPDATE car SET x = y, y = x WHERE <filter>
它至少可以在PostgreSQL(也在下面),SQLite3(下面),Oracle和MSSQL上正常工作,但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 :(得分:-1)
我不认为更新可以做到这一点,因为它基本上是一个sql包装器。 但是,你可以做的是使用save(values = [&#39; x&#39;,&#39; y&#39;])。希望它不会那么慢。 或者,您可以使用django中的原始sql来执行交换(请参阅Swap values for two rows in the same table in SQL Server)