【问题标题】:Foreign key relationship with peewee and python与peewee和python的外键关系
【发布时间】:2013-06-11 02:43:39
【问题描述】:

我正在尝试使用 peewee 设置数据库 ORM,但不清楚外键关系的使用。

from peewee import *

db = SqliteDatabase('datab.db')

class datab(Model):
    class Meta:
        database = db

class Collection(datab):
    identifier = CharField()
    title = CharField()

class File(datab):
    identifier = ForeignKeyField(Collection, related_name='files')
    name = CharField()

稍后,我会导入“Collections”

for value in collection:
Collection(**value).save()

最后,我遇到问题的地方是将文件添加到集合中

for value in collectionFiles:
    File(**value).save()

在值字典中,有一个关键字对,关键字为“标识符”,一个值应与集合标识符关键字相关联。

但是我收到一条错误消息:

ValueError: invalid literal for int() with base 10: 'somevalue'

如果我将 File(datab): identifier Type 更改为 VarChar,它会保存数据。

我意识到我做错了。我的假设是每个表中的唯一标识符值将应用外键。阅读文档后,看起来外键设置有点不同。我需要做类似的事情吗

Collections.File.files(**values).save() ?也就是说,不是做数据导入,而是加载集合对象,然后通过peewee添加文件关联字段?

组成类 File 的值

{'crc32': '63bee49d',
 'format': 'Metadata',
 'identifier': u'somevalue',
 'md5': '34104ffce9e4084fd3641d0decad910a',
 'mtime': '1368328224',
 'name': 'lupi.jpg_meta.txt',
 'sha1': '1448ed1159a5d770da76067dd1c53e94d5a01535',
 'size': '1244'}

【问题讨论】:

    标签: python orm peewee


    【解决方案1】:

    我认为您的字段命名可能是混淆的一部分。与其从 File -> Collection "identifier" 调用外键,不如将其称为 "collection"。

    class File(datab):
      collection = ForeignKeyField(Collection, related_name='files')
      name = CharField()
    

    Peewee 更喜欢在设置外键的值时,它是一个模型实例。例如,而不是这样做:

    File.create(collection='foobar', name='/secret/password')
    

    最好这样做:

    collection = Collection.get(Collection.identifier == 'foobar')
    File.create(collection=collection, name='/secret/password')
    

    最后一点,如果集合“标识符”是唯一的主键,您可以这样设置:

    class Collection(datab):
      identifier = CharField(primary_key=True)
      title = CharField()
    

    【讨论】:

    • 谢谢,我看到一些关于外键是模型实例的信息,但在实现上不清楚。集合和文件模型的字段比我在这里展示的要多——这就是我使用 kwargs 的原因。我想有了这里的两个答案,我就可以解决这个问题了。
    【解决方案2】:

    (我对peewee不熟悉,但如果它像Django那么这应该可以。)

    class File 有一个ForeignKeyField 和一个CharField,所以你不能简单地用File(**value) 保存一对字符串。您需要先将字符串转换为键,如下所示:

    for value in collectionFiles:
        identifier = value['identifier']
        name = value['name']
        collection_entity = Collection.objects.filter(identifier=identifier).get()
        File(identifier=collection_entity, name=name).save()
    

    【讨论】:

    • 嗯,在我尝试保存功能之前,我的 dict 中似乎包含正确的密钥对值组合。
    • @Justin,我认为你得到ValueError 的原因是因为它需要一个整数作为标识符,而不是u'somevalue'。整数是具有该标识符的相关Collection 的 ID(这就是数据库链接 ForeignKeyField 的方式)。
    • 我注意到代码不太正确,我将其修复为使用collection_entity
    • 啊,我明白了,出于某种原因,我认为它只是在寻找表之间键/值的唯一性。稍后会尝试一下
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多