Python版本3.6.8,peewee版本3.10.0
我使用peewee在sqlite数据库中设置了3个表。
Plan:
- id : int (primary key)
- plan_name : varchar (unique)
- status : int (foreign key for PlanStatus)
- category : int (foreign key for PlanCategory)
PlanStatus:
- id : int (primary key)
- value : varchar (unique)
PlanCategory:
- id : int (primary key)
- value : varchar (unique)PlanStatus是一个枚举引用表,PlanCategory是另一个枚举引用表。在下面的代码中,PlanStatus是用许多样板实现的,每个枚举表都必须重复这些样板。相反,PlanCategory继承自父类EnumBaseModel,包括两个类方法。目标是通过继承来减少样板文件。
结果是两个枚举表都被成功填充,您可以通过查询访问它们的值。但是,在创建计划条目时,会在数据库中添加一行(在sqlite中检查),但是select查询会返回缺少PlanCategory外键的行。
创建表和添加行:
from peewee import *
DATABASE = SqliteDatabase('test.db')
# Base class with the inner Meta class defined
class BaseModel(Model):
class Meta:
database = DATABASE
# PlanStatus class, used with the following 2 methods
class PlanStatus(BaseModel):
value = CharField(unique=True)
# Helper function for PlanStatus
def init_plan_status_values(values):
for value in values:
if not PlanStatus.select().where(PlanStatus.value == value).exists():
PlanStatus.create(value=value)
# Helper function for PlanStatus
def get_plan_status(value):
try:
return PlanStatus.get(PlanStatus.value == value)
except DoesNotExist as err:
return None
# Base class with 2 classmethods
class EnumBaseModel(BaseModel):
value = CharField(unique=True)
@classmethod
def init_values(cls, values):
for value in values:
if not cls.select().where(cls.value == value).exists():
cls.create(value=value)
@classmethod
def get(cls, value):
try:
return cls.select().where(cls.value == value).get()
except DoesNotExist as err:
return None
# PlanCategory inherits EnumBaseModel class and its 2 classmethods
class PlanCategory(EnumBaseModel):
pass
# Plan has 2 foreign keys
class Plan(BaseModel):
plan_name = CharField(unique=True)
status = ForeignKeyField(model=PlanStatus, backref='plans')
category = ForeignKeyField(model=PlanCategory, backref='plans')
DATABASE.connect()
DATABASE.create_tables(
[
PlanStatus,
PlanCategory,
Plan
],
safe=True
)
# Populating the enum values PlanStatus the explicit way above
init_plan_status_values(('STATUS-1', 'STATUS-2', 'STATUS-3'))
# Find status_2 the explicit way above
status_2 = get_plan_status('STATUS-2')
# Populating the enum values in PlanCategory using the inherited classmethod above
PlanCategory.init_values(('CATEGORY-1', 'CATEGORY-2', 'CATEGORY-3'))
# Find category_3 using the inherited classmethod above
category_3 = PlanCategory.get('CATEGORY-3')
# Add one plan
try:
Plan.create(
plan_name='not bad plan',
status=status_2,
category=category_3,
)
except IntegrityError as err:
print(err)现在,我们可以看到在sqlite3中成功添加了行:
SQLite version 3.22.0 2018-01-22 18:45:57
Enter ".help" for usage hints.
sqlite> .tables
plan plancategory planstatus
sqlite> select * from planstatus;
1|STATUS-1
2|STATUS-2
3|STATUS-3
sqlite> select * from plancategory;
1|CATEGORY-1
2|CATEGORY-2
3|CATEGORY-3
sqlite> select * from plan;
1|not bad plan|2|3
sqlite>现在检查select()查询中的计划条目,'a_plan.status‘是有效的,但是'a_plan.category’是None。
# We see the references status_2 and category_3 are valid
print('status_2 = ', type(status_2), status_2, status_2.value)
print('category_3 = ', type(category_3), category_3, category_3.value)
print()
# We check the one plan in the table and see now the foreign-key value "category" is missing
a_plan = Plan.get()
print('a_plan: plan_name={}, status={}, category={}'.format(
a_plan.plan_name,
a_plan.status,
a_plan.category
))
print()打印结果:
status_2 = <Model: PlanStatus> 2 STATUS-2
category_3 = <Model: PlanCategory> 3 CATEGORY-3
a_plan: plan_name=not bad plan, status=2, category=None此外,我还找到了peewee创建的属性'status_id‘和'category_id’。至少'category_id‘仍然保留外键int值。
# After inspecting dir(a_plan), found these attributes:
print('status = ', type(a_plan.status), a_plan.status)
print('status_id = ', type(a_plan.status_id), a_plan.status_id)
print('category = ', type(a_plan.category), a_plan.category)
print('category_id = ', type(a_plan.category_id), a_plan.category_id)打印结果:
status = <Model: PlanStatus> 2
status_id = <class 'int'> 2
category = <class 'NoneType'> None
category_id = <class 'int'> 3有没有办法解决这个问题,这样它就可以解决'a_plan.category‘了?
发布于 2019-09-11 05:24:01
您正在覆盖Peewee使用的方法(.get)。别干那事!我认为你把事情搞得太神奇了(并且在这个过程中到处都引入了查询)。
试着简化一下。我几乎可以保证问题出在你对Peewee依赖的类方法所做的重写中。
https://stackoverflow.com/questions/57878188
复制相似问题