在我的应用程序中,我有一个只有在运行时才知道列数的模型。使用下面的Factory这样的函数来创建模型很好地解决了这个问题。但是,如果我多次使用它(可能有不同的字段),创建外键ref会抛出一个异常:
AttributeError: Foreign key: dynamictable.ref related name "dynamictable_set"
collision with foreign key using same related_name.消息非常清楚,当我在创建外键时设置related_name参数时,没有错误。
问题
related_name?我也需要重新定义StaticTable吗?最小的、可复制的示例:
import peewee
database_proxy = peewee.Proxy()
class BaseModel(peewee.Model):
class Meta:
database = database_proxy
class StaticTable(BaseModel):
foo = peewee.DoubleField()
def Factory(fields):
class DynamicTable(BaseModel):
ref = peewee.ForeignKeyField(StaticTable)
for field in fields:
peewee.DoubleField().add_to_class(DynamicTable, field)
return DynamicTable
def Test(fname, fields):
db = peewee.SqliteDatabase(fname)
database_proxy.initialize(db)
db.create_table(StaticTable)
dyntable = Factory(fields)
db.create_table(dyntable)
db.close()
Test(':memory:', ['foo', 'bar'])
Test(':memory:', ['foo', 'bar', 'extra'])发布于 2014-11-18 23:28:30
我认为这突出了peewee中的一个bug,您可能明确地想忽略任何回退。我已经开了一张票,我会解决的。
https://github.com/coleifer/peewee/issues/465
同时,您可以通过在模型上设置一个动态related_name来消除错误。
def Factory(fields):
dynamic_name = '_'.join(fields)
class DynamicTable(BaseModel):
ref = peewee.ForeignKeyField(StaticTable, related_name=dynamic_name)
for field in fields:
peewee.DoubleField().add_to_class(DynamicTable, field)
return DynamicTable更新:根据#465中的修复程序,现在可以禁用backref验证:
def Factory(fields):
class DynamicTable(BaseModel):
ref = peewee.ForeignKeyField(StaticTable, related_name=dynamic_name)
class Meta:
validate_backrefs = False
for field in fields:
peewee.DoubleField().add_to_class(DynamicTable, field)
return DynamicTable发布于 2014-11-19 09:58:16
@coleifer的建议(在他的回答中)很有效,只要字段列表是唯一的。由于在我的例子中不能保证这一点,所以我想出了一个稍微复杂一些的解决方案,其中所有的模型类都是在工厂中创建的:
import peewee
database_proxy = peewee.Proxy()
def orm_factory():
class OrmWrapper:
class BaseModel(peewee.Model):
class Meta:
database = database_proxy
class StaticTable(BaseModel):
foo = peewee.DoubleField()
@classmethod
def dyntable_factory(cls,fields):
class DynamicTable(cls.BaseModel):
ref = peewee.ForeignKeyField(cls.StaticTable)
for field in fields:
peewee.DoubleField().add_to_class(DynamicTable, field)
return DynamicTable
return OrmWrapper
def test(fname, fields):
orm = orm_factory()
db = peewee.SqliteDatabase(fname)
database_proxy.initialize(db)
db.create_table(orm.StaticTable)
dyntable = orm.dyntable_factory(fields)
db.create_table(dyntable)
db.close()
test(':memory:', ['foo', 'bar'])
test(':memory:', ['foo', 'bar'])https://stackoverflow.com/questions/27000279
复制相似问题