0

我正在尝试为 Peewee 构建数据库驱动程序,但在获取save()填充对象主键/ID 的方法时遇到了麻烦。这是一些示例代码:

from datetime import date
from peewee import BooleanField
from peewee import CharField
from peewee import DateField
from peewee import ForeignKeyField
from peewee import IntegerField
from peewee import Model
from SQLRelay import PySQLRDB
from sqlrelay_ext import SQLRelayDatabase

DB = SQLRelayDatabase('test2', host='<host>', user='<un>', password='<pwd>')

class BaseModel(Model):
    class Meta:
        database = DB

class Person(BaseModel):
    name = CharField()
    birthday = DateField()
    is_relative = BooleanField()

class Pet(BaseModel):
    owner = ForeignKeyField(Person, backref='pets')
    name = CharField()
    animal_type = CharField()

DB.connect()
Person.create_table(safe=False)
Pet.create_table(safe=False)
uncle_bob = Person(name='Bob', birthday=date(1960, 1, 15), is_relative=True)
uncle_bob.save() # bob is now stored in the database
print('Uncle Bob id: {}'.format(uncle_bob.id))
print('Uncle Bob _pk: {}'.format(uncle_bob._pk))

两者uncle_bob.iduncle_bob._pkNone之后.save()。从深入研究peewee.py代码来看,该_WriteQuery.execute()方法似乎应该设置_pk属性,但这并没有发生。我最好的猜测是游标实现没有正确运行。有没有人比这更有洞察力,可以帮助我找出这个问题?

谢谢!

编辑回答:

对于 SQL Server,以下代码允许您返回最后插入的 id:

def last_insert_id(self, cursor, query_type=None):
    try:
        cursor.execute('SELECT SCOPE_IDENTITY()')
        result = cursor.fetchone()
        return result[0]
    except (IndexError, KeyError, TypeError):
        pass
4

1 回答 1

1

在您的SQLRelayDatabase实现中,您可能需要正确实现该last_insert_id()方法。对于 python db-api 2.0 驱动程序,这通常看起来像cursor.lastrowid.

默认实现是:

def last_insert_id(self, cursor, query_type=None):
    return cursor.lastrowid

cursor用于执行插入查询的游标对象在哪里。

像 Postgresql 这样的数据库没有实现这一点——而是执行一个 INSERT...RETURNING 查询,所以 Postgres 的实现有点不同。postgres 实现确保您的插入查询包含一个 RETURNING 子句,然后获取返回的 id。

根据您的数据库和底层数据库驱动程序,您需要以某种方式拉出最后一个插入 id。last_insert_id()假设已实施,Peewee 应该处理其余部分。

于 2018-05-10T18:16:59.870 回答