尝试使用 Peewee 输入 ForeignKey 字段时出现 AttributeError
AttributeError when attempting to enter ForeignKey fields with Peewee
我真的很费时间试图找出我收到的错误消息的原因。
我正在编写一个网络抓取工具,使用 Python 将数据从 Procycing Stats 抓取到 MySQL 数据库中,使用 BeautifulSoup 进行抓取,使用 Peewee 进行数据库交互。网络抓取工具工作得很好,但我在将数据插入 MySQL tables.
时遇到了一些麻烦
首先,我使用 peewee 的 create_tables()
函数在空数据库中创建了 table。在下面,我粘贴了我的 Peewee 模型的代码,该代码包含在我称为 peewee_lib.py
的文件中。
from peewee import *
from mysql_login_info import *
results_database = MySQLDatabase(mysql_db_name, user=mysql_uname, password=mysql_pw, host='localhost')
class BaseModel(Model):
class Meta:
database = results_database
class Rider(BaseModel):
pcsid = IntegerField()
name = CharField()
class Race(BaseModel):
name = CharField()
class Result(BaseModel):
name = CharField()
year = IntegerField()
date = DateField()
position = IntegerField()
points_pcs = IntegerField()
race = ForeignKeyField(Race, backref='results')
rider = ForeignKeyField(Rider, backref='results')
接下来,我使用一个文件 scrape_to_peewee.py
创建 class 那些 "bind" 我的 class 从我的抓取库 scraper_lib.py
和前面提到的定义peewee 图书馆,peewee_lib.py
。
这是来自 scrape_to_peewee.py
的代码:
import scraper_lib as pylib
import peewee_lib as pw
class Sheet_bind:
def __init__(self, rider_obj, sheet):
self.year = sheet.year
self.rider = sheet.rider
self.rows = []
for row in sheet.rows:
if row.row_type == "tour_header":
pass
else:
temp_query = pw.Race.select().where(pw.Race.name == row.race)
if not temp_query.exists():
temp_query = pw.Race(name=row.race)
temp_query.save()
else:
pass
temp_res = pw.Result(name=row.name,\
year=sheet.year,\
position=row.result,\
points_pcs=row.points_pcs)
if row.row_type in ["stage", "classification"]:
temp_res.name = row.race + ' ' + row.name
temp_res.race=temp_query
temp_res.rider=rider_obj
temp_res.save()
temp_query = None
temp_res = None
class Rider_bind:
def __init__(self, rider_id):
self.rider_py = pylib.Rider(rider_id)
self.rider_pw = pw.Rider(pcsid=self.rider_py.url_id, name=self.rider_py.name)
self.rider_pw.save()
def load_sheets(self, start_year, end_year):
for year in xrange(start_year, end_year + 1):
if year not in self.rider_py.sheets:
self.rider_py.load_sheets(year, year)
loaded_sheet = Sheet_bind(self.rider_pw, self.rider_py.sheets[year])
loaded_sheet.save()
def main():
pw.results_database.connect()
main()
将这个最终文件加载到解释器中后,我尝试将示例车手加载到数据库中。启动 Rider_bind
class 工作正常,我仔细检查以确保一行实际上已写入 MySQL 中的 rider
table,它有。但是,当我尝试使用 Rider_bind.load_sheets()
将结果加载到数据库中时,出现以下错误:
$ python
Python 2.7.15rc1 (default, Nov 12 2018, 14:31:15)
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from scrape_to_peewee import *
>>> olly = Rider_bind("oliver-naesen")
>>> olly.load_sheets(2018, 2018)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "scrape_to_peewee.py", line 55, in load_sheets
loaded_sheet = Sheet_bind(self.rider_pw, self.rider_py.sheets[year])
File "scrape_to_peewee.py", line 33, in __init__
temp_res.race=temp_query
File "/home/trenza/.local/lib/python2.7/site-packages/peewee.py", line 3848, in __set__
if obj != fk_value and self.name in instance.__rel__:
File "/home/trenza/.local/lib/python2.7/site-packages/peewee.py", line 726, in __ne__
return not (self == other)
File "/home/trenza/.local/lib/python2.7/site-packages/peewee.py", line 723, in __eq__
return self._hash == other._hash
AttributeError: 'NoneType' object has no attribute '_hash'
问题似乎与将其中一个 peewee 模型分配给外键字段有关。当我颠倒调用顺序以便 temp_res.rider = rider_obj
排在第一位时,它给了我同样的错误,回溯指向该调用。
从 peewee 文档看来,ForeignKey 字段应该像将另一个 peewee class 作为值分配给它们一样简单。有谁知道我在这里弄错了什么?任何帮助将非常感激。
谢谢!
编辑:
不是 this question 的副本,因为它(据我所知)与 select
调用中的 return 值无关(上述问题中的问题) .
分配给属性时,您需要将 "temp_query" 解析为对象。
if not temp_query.exists():
temp_query = pw.Race(name=row.race)
temp_query.save()
else:
temp_query = temp_query.get() # fixed.
我真的很费时间试图找出我收到的错误消息的原因。
我正在编写一个网络抓取工具,使用 Python 将数据从 Procycing Stats 抓取到 MySQL 数据库中,使用 BeautifulSoup 进行抓取,使用 Peewee 进行数据库交互。网络抓取工具工作得很好,但我在将数据插入 MySQL tables.
时遇到了一些麻烦首先,我使用 peewee 的 create_tables()
函数在空数据库中创建了 table。在下面,我粘贴了我的 Peewee 模型的代码,该代码包含在我称为 peewee_lib.py
的文件中。
from peewee import *
from mysql_login_info import *
results_database = MySQLDatabase(mysql_db_name, user=mysql_uname, password=mysql_pw, host='localhost')
class BaseModel(Model):
class Meta:
database = results_database
class Rider(BaseModel):
pcsid = IntegerField()
name = CharField()
class Race(BaseModel):
name = CharField()
class Result(BaseModel):
name = CharField()
year = IntegerField()
date = DateField()
position = IntegerField()
points_pcs = IntegerField()
race = ForeignKeyField(Race, backref='results')
rider = ForeignKeyField(Rider, backref='results')
接下来,我使用一个文件 scrape_to_peewee.py
创建 class 那些 "bind" 我的 class 从我的抓取库 scraper_lib.py
和前面提到的定义peewee 图书馆,peewee_lib.py
。
这是来自 scrape_to_peewee.py
的代码:
import scraper_lib as pylib
import peewee_lib as pw
class Sheet_bind:
def __init__(self, rider_obj, sheet):
self.year = sheet.year
self.rider = sheet.rider
self.rows = []
for row in sheet.rows:
if row.row_type == "tour_header":
pass
else:
temp_query = pw.Race.select().where(pw.Race.name == row.race)
if not temp_query.exists():
temp_query = pw.Race(name=row.race)
temp_query.save()
else:
pass
temp_res = pw.Result(name=row.name,\
year=sheet.year,\
position=row.result,\
points_pcs=row.points_pcs)
if row.row_type in ["stage", "classification"]:
temp_res.name = row.race + ' ' + row.name
temp_res.race=temp_query
temp_res.rider=rider_obj
temp_res.save()
temp_query = None
temp_res = None
class Rider_bind:
def __init__(self, rider_id):
self.rider_py = pylib.Rider(rider_id)
self.rider_pw = pw.Rider(pcsid=self.rider_py.url_id, name=self.rider_py.name)
self.rider_pw.save()
def load_sheets(self, start_year, end_year):
for year in xrange(start_year, end_year + 1):
if year not in self.rider_py.sheets:
self.rider_py.load_sheets(year, year)
loaded_sheet = Sheet_bind(self.rider_pw, self.rider_py.sheets[year])
loaded_sheet.save()
def main():
pw.results_database.connect()
main()
将这个最终文件加载到解释器中后,我尝试将示例车手加载到数据库中。启动 Rider_bind
class 工作正常,我仔细检查以确保一行实际上已写入 MySQL 中的 rider
table,它有。但是,当我尝试使用 Rider_bind.load_sheets()
将结果加载到数据库中时,出现以下错误:
$ python
Python 2.7.15rc1 (default, Nov 12 2018, 14:31:15)
[GCC 7.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from scrape_to_peewee import *
>>> olly = Rider_bind("oliver-naesen")
>>> olly.load_sheets(2018, 2018)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "scrape_to_peewee.py", line 55, in load_sheets
loaded_sheet = Sheet_bind(self.rider_pw, self.rider_py.sheets[year])
File "scrape_to_peewee.py", line 33, in __init__
temp_res.race=temp_query
File "/home/trenza/.local/lib/python2.7/site-packages/peewee.py", line 3848, in __set__
if obj != fk_value and self.name in instance.__rel__:
File "/home/trenza/.local/lib/python2.7/site-packages/peewee.py", line 726, in __ne__
return not (self == other)
File "/home/trenza/.local/lib/python2.7/site-packages/peewee.py", line 723, in __eq__
return self._hash == other._hash
AttributeError: 'NoneType' object has no attribute '_hash'
问题似乎与将其中一个 peewee 模型分配给外键字段有关。当我颠倒调用顺序以便 temp_res.rider = rider_obj
排在第一位时,它给了我同样的错误,回溯指向该调用。
从 peewee 文档看来,ForeignKey 字段应该像将另一个 peewee class 作为值分配给它们一样简单。有谁知道我在这里弄错了什么?任何帮助将非常感激。
谢谢!
编辑:
不是 this question 的副本,因为它(据我所知)与 select
调用中的 return 值无关(上述问题中的问题) .
分配给属性时,您需要将 "temp_query" 解析为对象。
if not temp_query.exists():
temp_query = pw.Race(name=row.race)
temp_query.save()
else:
temp_query = temp_query.get() # fixed.