У меня действительно самое ужасное время, чтобы понять причину сообщения об ошибке, которое я получаю.
Я пишу веб-скребок, который очищает данные от Статистика обработки в базу данных MySQL, используя Python с BeautifulSoup для очистки и Peewee для взаимодействия с базой данных.Веб-скребок работает совершенно нормально, но у меня возникли некоторые проблемы с вставкой данных в таблицы MySQL.
Во-первых, я создал таблицы в пустой базе данных с помощью функции create_tables()
peewee.Ниже я вставил код для моих моделей 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
для создания классов, которые "связывают" вместе мои определения классов из моей библиотеки скребков 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
работало нормально, и я дважды проверил, чтобы убедиться, что строка действительно записана в мою таблицу rider
в MySQL, которая у него была.Однако, когда я пытаюсь загрузить результаты в базу данных с помощью 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 для поля Foreignkey.Когда я перевернул порядок вызовов так, чтобы temp_res.rider = rider_obj
был первым, это дало мне ту же ошибку с трассировкой, указывающей на этот вызов.
Из документов peewee кажется, что поля ForeignKey должны быть такими же простыми, как просто присвоение им другого класса peewee в качестве значения.Кто-нибудь знает, что я здесь не так?Любая помощь приветствуется.
Спасибо!
Редактировать:
Не дубликат этот вопрос , поскольку он (насколько я знаю) не связан с возвратомзначение из select
вызова (проблема в вышеупомянутом вопросе).