Python 如何加快在数据库中的写入速度?
我有一个在目录中搜索json文件、解析文件和在数据库中写入数据的函数。我的问题是在数据库中写入,因为它需要大约30分钟。你知道我如何加快在数据库中的写入速度吗?我有几个相当大的文件要解析,但解析文件不是问题,大约需要3分钟。目前我正在使用sqlite,但将来我会将其更改为PostgreSQL 以下是我的功能:Python 如何加快在数据库中的写入速度?,python,django,database,sqlite,Python,Django,Database,Sqlite,我有一个在目录中搜索json文件、解析文件和在数据库中写入数据的函数。我的问题是在数据库中写入,因为它需要大约30分钟。你知道我如何加快在数据库中的写入速度吗?我有几个相当大的文件要解析,但解析文件不是问题,大约需要3分钟。目前我正在使用sqlite,但将来我会将其更改为PostgreSQL 以下是我的功能: def create_database(): with transaction.atomic(): directory = os.fsencode('data/we
def create_database():
with transaction.atomic():
directory = os.fsencode('data/web_files/unzip')
for file in os.listdir(directory):
filename = os.fsdecode(file)
with open('data/web_files/unzip/{}'.format(filename.strip()), encoding="utf8") as f:
data = json.load(f)
cve_items = data['CVE_Items']
for i in range(len(cve_items)):
database_object = DataNist()
try:
impact = cve_items[i]['impact']['baseMetricV2']
database_object.severity = impact['severity']
database_object.exp_score = impact['exploitabilityScore']
database_object.impact_score = impact['impactScore']
database_object.cvss_score = impact['cvssV2']['baseScore']
except KeyError:
database_object.severity = ''
database_object.exp_score = ''
database_object.impact_score = ''
database_object.cvss_score = ''
for vendor_data in cve_items[i]['cve']['affects']['vendor']['vendor_data']:
database_object.vendor_name = vendor_data['vendor_name']
for description_data in cve_items[i]['cve']['description']['description_data']:
database_object.description = description_data['value']
for product_data in vendor_data['product']['product_data']:
database_object.product_name = product_data['product_name']
database_object.save()
for version_data in product_data['version']['version_data']:
if version_data['version_value'] != '-':
database_object.versions_set.create(version=version_data['version_value'])
My models.py:
class DataNist(models.Model):
vendor_name = models.CharField(max_length=100)
product_name = models.CharField(max_length=100)
description = models.TextField()
date = models.DateTimeField(default=timezone.now)
severity = models.CharField(max_length=10)
exp_score = models.IntegerField()
impact_score = models.IntegerField()
cvss_score = models.IntegerField()
def __str__(self):
return self.vendor_name + "-" + self.product_name
class Versions(models.Model):
data = models.ForeignKey(DataNist, on_delete=models.CASCADE)
version = models.CharField(max_length=50)
def __str__(self):
return self.version
如果您能给我一些如何改进代码的建议,我将不胜感激。好的,考虑到数据的结构,类似的方法可能适合您 除了.objects.bulk\u create调用之外,这是独立的代码;正如代码中所述,定义的两个类实际上是Django应用程序中的模型。 顺便说一下,您可能也希望将CVE ID保存为唯一字段 您的原始代码错误地假设受影响版本数据中的每个叶条目都有相同的供应商,这可能不是真的。这就是为什么这里的模型结构有一个单独的产品版本模型,其中包含供应商、产品和版本字段。如果您想稍微优化一下,您可能会消除受影响的ProductVersions,甚至是跨DataNists的重复数据,顺便说一句,这对于模型来说并不是一个完美的名称 当然,正如您在原始代码中所做的那样,导入应该在transaction.atomic中运行 希望这有帮助 导入json 导入操作系统 导入类型 类DataNisttypes.SimpleNamespace:这实际上是一个模型 严重性= 经验分数= 影响评分= cvss_分数= def saveself: 通过 类影响ProductVersionTypes.SimpleNamespace:这也是 这里是DataNist的外键 供应商名称= 产品名称= 版本\u值= def导入_项目: 数据库\u对象=DataNist 尝试: 影响=项目[影响][baseMetricV2] KeyError除外:没有可用的碰撞对象 通过 其他: 数据库_object.severity=impact.getseverity, database_object.exp_score=impact.getExplorabilityScore, 数据库\u object.impact\u score=impact.getimpactScore, 如果cvssV2发生碰撞: 数据库_object.cvss_score=影响[cvssV2][baseScore] 对于项目[cve][description][description\u data]中的描述数据: 数据库\u object.description=描述\u数据[值] 只抓取第一个描述 数据库\u对象。保存基本对象 受影响的_版本=[] 对于【cve】【影响】【供应商】【供应商数据】项中的供应商数据: 对于供应商数据[产品][产品数据]中的产品数据: 对于产品数据[版本][版本数据]中的版本数据: 受影响的_versions.append 影响产品版本 数据=数据库对象, 供应商名称=供应商数据[供应商名称], 产品名称=产品数据[产品名称], 版本名称=版本数据[版本值], AffectedProductVersion.objects.bulk\u创建 受影响的版本 保存所有版本信息 返回数据库_对象,以防调用者需要它 使用opennvdcve-1.0-2019.json作为infp: data=json.loadinfp 对于数据中的项[CVE_项]: 导入项目
您的代码似乎正在覆盖同一数据库对象中的.vendor\u name、.description和.product\u name。这就是你真正想要的吗?@AKX我得到了我想要的结果,但要得到它需要很多。我是初级python程序员,我正在寻找任何有用的建议,如何优化和加速我的代码。我只是说你可能有一个bug,因为你在一个循环中覆盖了这些值。此外,如果有多个product_数据项,你在用不同的product_名称保存同一个对象,第三,如果try:except KeyError:block中的四个键中的任何一个丢失,那么数据库对象中的所有值都将被清除。这听起来不是正确的行为。现在我有一个问题,如何在我的项目中实现它。我不明白你的模型是如何工作的,以及放在哪里。我应该删除现有的模型并用你的模型替换它们吗?我将我的models.py添加到我的问题中。我的模型没有什么特别之处,因为它们在答案中不是真正的模型,因为它的设计主要是独立的可运行代码。你至少应该调整你的版本类顺便说一句,类名应该是单数,以有我的版本的三个字段;否则,这个数据模型看起来不错。objects.bulk\u create接受它将创建的未保存模型对象的列表,请参阅文档。我正在尝试将database\u对象指定给AffectedProductVersion中的变量,但不知道如何进行。如果我尝试像您一样执行此操作,则会得到错误表db_affectedproductversion没有列na med data\u nist\u id。我尝试了其他一些方法,但没有成功。您的模型具有data=models.ForeignKeyDataNist,on\u delete=models.CASCADE,而不是data\u nist=…,因此请改用data=database\u对象。