我正在尝试为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.id
之后uncle_bob._pk
和None
.save()
都是peewee.py
。从挖掘到_WriteQuery.execute()
代码,似乎_pk
方法应该设置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
属性,但这不会发生。我最好的猜测是光标实现没有正常运行。有没有人比这更有洞察力可以帮助我追踪这个问题?
谢谢!
编辑回答:
对于SQL Server,以下代码允许您返回最后插入的ID:
{{1}}
答案 0 :(得分: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应该处理剩下的事情。