我想用Django更新一个表 - 在原始SQL中是这样的:
update tbl_name set name = 'foo' where name = 'bar'
Run Code Online (Sandbox Code Playgroud)
我的第一个结果是这样的 - 但这很讨厌,不是吗?
list = ModelClass.objects.filter(name = 'bar')
for obj in list:
obj.name = 'foo'
obj.save()
Run Code Online (Sandbox Code Playgroud)
有更优雅的方式吗?
我必须使用Django的ORM将8000多条记录插入到SQLite数据库中.此操作需要每分钟大约运行一次cronjob.
目前我正在使用for循环迭代所有项目,然后逐个插入它们.
例:
for item in items:
entry = Entry(a1=item.a1, a2=item.a2)
entry.save()
Run Code Online (Sandbox Code Playgroud)
这样做的有效方法是什么?
编辑:两种插入方法之间的一点比较.
没有commit_manually装饰器(11245条记录):
nox@noxdevel marinetraffic]$ time python manage.py insrec
real 1m50.288s
user 0m6.710s
sys 0m23.445s
Run Code Online (Sandbox Code Playgroud)
使用commit_manually decorator(11245条记录):
[nox@noxdevel marinetraffic]$ time python manage.py insrec
real 0m18.464s
user 0m5.433s
sys 0m10.163s
Run Code Online (Sandbox Code Playgroud)
注意:除了插入数据库之外,测试脚本还执行一些其他操作(下载ZIP文件,从ZIP存档中提取XML文件,解析XML文件),因此执行所需的时间不一定代表插入所需的时间记录.
有没有更有效的方法来做到这一点?
for item in item_list:
e, new = Entry.objects.get_or_create(
field1 = item.field1,
field2 = item.field2,
)
Run Code Online (Sandbox Code Playgroud) 我需要将大量数据上传到MySQL数据库.对于大多数模型,我使用django的ORM,但我的一个模型将有数十亿(!)的实例,我想优化其插入操作.
我似乎无法找到使executemany()工作的方法,并且在谷歌搜索后似乎几乎没有任何例子.
我正在寻找正确的sql语法+正确的命令语法+正确的值数据结构,以支持以下sql语句的executemany命令:
INSERT INTO `some_table` (`int_column1`, `float_column2`, `string_column3`, `datetime_column4`) VALUES (%d, %f, %s, %s)
Run Code Online (Sandbox Code Playgroud)
是的,我明确说明了id(int_column1)的效率.
一个简短的示例代码会很棒
我bulk_create用来将1个mio记录插入到新表中.这需要80秒.Django只使用一个CPU核心(大约25%的CPU,但没有核心达到100%)我相信有改进潜力.
这是代码
class Stock(models.Model):
code = models.CharField(max_length=6, unique=True)
name = models.CharField(max_length=8)
class Watchers(models.Model):
date = models.DateField(db_index=True)
stock = models.ForeignKey(Stock, unique_for_date="date")
num = models.PositiveIntegerField(default=0)
batch = []
for input in inputs:
watcher = Watcher(date=input['date'], stock=get_stock(), num=input['num'])
batch.append(watcher)
Watcher.objects.bulk_create(batch)
Run Code Online (Sandbox Code Playgroud)
我尝试了几件事:
batch_size.对我来说最好的价值大约是4000.它需要80-90秒.ThreadPool().它慢得多,大约120-140秒DateField.比1慢一点.我正在使用MySQL 5.6社区版.存储引擎是MyISAM.这是配置.
[mysqld]
server-id = 1
default-storage-engine = MyISAM
port = 3306
socket = /tmp/mysql.sock
datadir = "{MYSQLDATAPATH}"
skip-external-locking
explicit_defaults_for_timestamp = TRUE
# MyISAM #
key-buffer-size = 32M
max_allowed_packet = 16M …Run Code Online (Sandbox Code Playgroud) 我决定使用django的模型系统而不是编写原始SQL来与我的数据库接口,但我遇到的问题肯定是可以避免的.
我的models.py包含:
class Student(models.Model):
student_id = models.IntegerField(unique = True)
form = models.CharField(max_length = 10)
preferred = models.CharField(max_length = 70)
surname = models.CharField(max_length = 70)
Run Code Online (Sandbox Code Playgroud)
我通过循环遍历列表来填充它,如下所示:
from models import Student
for id, frm, pref, sname in large_list_of_data:
s = Student(student_id = id, form = frm, preferred = pref, surname = sname)
s.save()
Run Code Online (Sandbox Code Playgroud)
我真的不想每次都将它保存到数据库中,但我不知道另一种方法让django不要忘记它(我宁愿添加所有行然后再做一次提交).
代码有两个问题.
这很慢 - 大约20名学生每秒更新一次.
它甚至没有通过large_list_of_data,而是抛出一个说"无法打开数据库文件"的DatabaseError.(可能是因为我使用的是sqlite3.)
我的问题是:我怎样才能阻止这两件事发生?我猜这两个问题的根源是我有s.save()但是我没有看到一种方法可以轻松地将学生批处理,然后将它们保存在数据库的一次提交中.
我正在尝试使用peewee对sqlite数据库进行大规模批量插入.我正在使用,atomic但性能仍然很糟糕.我在〜2500行的块中插入行,由于SQL_MAX_VARIABLE_NUMBER,我一次插入大约200行.这是代码:
with helper.db.atomic():
for i in range(0,len(expression_samples),step):
gtd.GeneExpressionRead.insert_many(expression_samples[i:i+step]).execute()
Run Code Online (Sandbox Code Playgroud)
列表expression_samples是一个字典列表,其中包含GeneExpressionRead模型的相应字段.我已经定时了这个循环,执行时需要2-8秒.我有数百万行要插入,现在我编写代码的方式可能需要2天才能完成.根据这篇文章,我设置了几个pragma以提高性能.对于我来说,这也没有真正改变任何表现.最后,根据peewee github页面上的这个测试,应该可以非常快地插入很多行(在0.3364秒内大约50,000个),但似乎作者使用原始的sql代码来获得这种性能.有没有人能够使用peewee方法做这么高性能的插入?
编辑:没有意识到peewee的github页面上的测试是针对MySQL插入的.可能适用于或不适用于这种情况.