用于加载.dat文件的Python脚本
import csv
from django.core.management.base import BaseCommand
from recommender.models import User, Artist, Tag, UserArtist, UserTaggedArtist, UserFriend
import os
from django.conf import settings
# Define the path to the database directory
Database_path = os.path.join(settings.BASE_DIR, 'mldata')
class Command(BaseCommand):
help = 'Load data from .dat files into the databases'
def handle(self, *args, **kwargs):
self.create_default_users()
self.load_artists()
self.load_tags()
self.load_user_artists()
self.load_user_tagged_artists()
self.load_user_friends()
def create_default_users(self):
users = [
{'username': 'User1', 'email': '[email protected]'},
{'username': 'User2', 'email': '[email protected]'}
]
for user in users:
User.objects.get_or_create(username=user['username'], email=user['email'])
def load_artists(self):
with open(os.path.join(Database_path, 'artists.dat'), 'r', encoding='utf-8', errors='replace') as file:
reader = csv.reader(file, delimiter='\t')
next(reader)
for row in reader:
artist_id, artist_name = row[0], row[1]
Artist.objects.get_or_create(artist_id=artist_id, defaults={'artist_name': artist_name})
def load_tags(self):
with open(os.path.join(Database_path, 'tags.dat'), 'r', encoding='utf-8', errors='replace') as file:
reader = csv.reader(file, delimiter='\t')
next(reader)
for row in reader:
tag_id, tag_name = row[0], row[1]
Tag.objects.get_or_create(tag_id=tag_id, defaults={'tag_name': tag_name})
def load_user_artists(self):
with open(os.path.join(Database_path, 'user_artists.dat'), 'r', encoding='utf-8', errors='replace') as file:
reader = csv.reader(file, delimiter='\t')
next(reader)
for row in reader:
user_id, artist_id, listening_count = row[0], row[1], row[2]
user = User.objects.get(id=user_id)
artist = Artist.objects.get(artist_id=artist_id)
UserArtist.objects.get_or_create(user=user, artist=artist, defaults={'listening_count': listening_count})
def load_user_tagged_artists(self):
with open(os.path.join(Database_path, 'user_taggedartists.dat'), 'r', encoding='utf-8', errors='replace') as file:
reader = csv.reader(file, delimiter='\t')
next(reader)
for row in reader:
user_id, artist_id, tag_id, timestamp = row[0], row[1], row[2], row[3]
user = User.objects.get(id=user_id)
artist = Artist.objects.get(artist_id=artist_id)
tag = Tag.objects.get(tag_id=tag_id)
UserTaggedArtist.objects.get_or_create(user=user, artist=artist, tag=tag, defaults={'timestamp': timestamp})
def load_user_friends(self):
with open(os.path.join(Database_path, 'user_friends.dat'), 'r', encoding='utf-8', errors='replace') as file:
reader = csv.reader(file, delimiter='\t')
next(reader)
for row in reader:
user_id, friend_id = row[0], row[1]
user = User.objects.get(id=user_id)
friend = User.objects.get(id=friend_id)
UserFriend.objects.get_or_create(user=user, friend=friend)
错误
File "C:\Users\ADMIN\OneDrive\Desktop\rml\myenv\Lib\site-packages\django\db\models\query.py", line 649, in get
raise self.model.DoesNotExist(
recommender.models.User.DoesNotExist: User matching query does not exist.
我这是什么,我不盲目地模仿,但我似乎不明白它到底想做什么,并且错误不断重复出现。
有人可以解释一下这段代码是什么吗是以及如何修复该错误
这段 Python 脚本用于将 Last.fm 数据集(以.dat 文件形式提供)加载到 Django 应用程序的数据库中。让我们将其分解为各个部分:
1. 导入语句
-
import csv
:这行代码导入用于处理 CSV(逗号分隔值)文件的csv
模块。在本例中,它用于读取以制表符分隔的 .dat 文件。 -
from django.core.management.base import BaseCommand
:这从 Django 导入BaseCommand
类,允许你创建自定义管理命令。 -
from recommender.models import User, Artist, Tag, UserArtist, UserTaggedArtist, UserFriend
:这从你的 Django 应用程序(“recommender”)中导入必要的模型,以代表数据库中的不同实体(用户、艺术家、标签、用户与艺术家之间的关系等)。 -
import os
:这将导入os
模块,以处理与操作系统相关的功能,例如构建文件路径。 -
from django.conf import settings
:这将导入settings
,让你访问 Django 项目的配置设置。
2.
Database_path
变量
-
Database_path = os.path.join(settings.BASE_DIR, 'mldata')
:这行代码定义了存储 .dat 文件的数据库目录的路径。它使用os.path.join
以独立于平台的方式连接路径组件。settings.BASE_DIR
指的是 Django 项目的根目录,mldata
是数据库目录的名称。
3.
Command
类
-
这段代码定义了一个继承自 Django
BaseCommand
类的自定义管理命令。这让你可以通过 Django 的命令行界面运行 Python 脚本。
4.
handle()
方法
-
handle()
方法是当你运行此管理命令时调用的主要入口点。它调用其他方法来加载不同的数据集。
5. 数据加载方法
-
create_default_users()
:此方法创建两个默认用户(“User1”和“User2”)及其电子邮件地址。它使用get_or_create()
以避免创建重复的用户。 -
load_artists()
、load_tags()
、load_user_artists()
、load_user_tagged_artists()
、load_user_friends()
:这些方法遵循类似的模式来加载不同的数据集。-
它们打开一个特定的 .dat 文件以进行读取 (
'r'
),使用utf-8
编码,并用csv.reader
处理制表符分隔的数据。 -
它们跳过第一行(标题行),使用
next(reader)
。 -
它们遍历文件的每一行,提取相关数据,然后使用
get_or_create()
在相应数据库表中创建对象。这可以确保不会创建重复的条目。
-
它们打开一个特定的 .dat 文件以进行读取 (
错误及修复
你遇到的错误是
recommender.models.User.DoesNotExist: User matching query does not exist.
这意味着你的脚本试图访问一个 ID 不存在于你的
User
表中的
User
对象。这可能发生在
load_user_artists()
、
load_user_tagged_artists()
或
load_user_friends()
方法中,其中脚本使用从 .dat 文件中读取的
user_id
来获取
User
对象。
为了解决这个问题,你需要确保你的
.dat
文件中引用的
user_id
存在于你的数据库中。你可以执行以下操作:
-
验证你的数据:
检查你的
.dat
文件,确保user_id
是正确的,并且与你的User
表中的现有用户相对应。 -
在加载其他数据之前加载用户数据:
确保你的脚本首先加载
users.dat
文件(或包含用户信息的文件),然后再加载引用用户的其他文件。 -
调整数据加载顺序:
如果你的
.dat
文件中有依赖关系(例如,user_artists.dat
依赖于users.dat
和artists.dat
),请确保按照正确的顺序加载文件。
通过仔细检查你的数据和脚本的执行流程,你应该能够识别出不一致之处,并解决
User.DoesNotExist
错误。