Existe-t-il un moyen d'obtenir les clés primaires des éléments que vous avez créés en utilisant la fonction bulk_create dans django 1.4+ ?
Réponses
Trop de publicités?# datatime.py
# my datatime function
def getTimeStamp(needFormat=0, formatMS=True):
if needFormat != 0:
return datetime.datetime.now().strftime(f'%Y-%m-%d %H:%M:%S{r".%f" if formatMS else ""}')
else:
ft = time.time()
return (ft if formatMS else int(ft))
def getTimeStampString():
return str(getTimeStamp()).replace('.', '')
# model
bulk_marker = models.CharField(max_length=32, blank=True, null=True, verbose_name='bulk_marker', help_text='ONLYFOR_bulkCreate')
# views
import .........getTimeStampString
data_list(
Category(title="title1", bulk_marker=getTimeStampString()),
...
)
# bulk_create
Category.objects.bulk_create(data_list)
# Get primary Key id
Category.objects.filter(bulk_marker=bulk_marker).values_list('id', flat=True)
J'ai essayé de nombreuses stratégies pour contourner cette limitation de MariaDB/MySQL. La seule solution fiable que j'ai trouvée à la fin était de générer les clés primaires dans l'application. NE PAS générer INT AUTO_INCREMENT
les champs PK vous-même, cela ne fonctionnera pas, pas même dans une transaction avec un niveau d'isolement serializable
car le compteur PK de MariaDB n'est pas protégé par des verrous de transaction.
La solution consiste à ajouter des UUID
aux modèles, génèrent leurs valeurs dans la classe de modèle, puis les utilisent comme identifiant. Lorsque vous enregistrez un groupe de modèles dans la base de données, vous ne récupérez toujours pas leur PK réel, mais ce n'est pas grave, car dans les requêtes ultérieures, vous pouvez les identifier de manière unique grâce à leur UUID.
En documentation sur django actuellement les états sous les limitations :
Si la clé primaire du modèle est un définir l'attribut de la clé primaire, comme
save()
fait.
Mais, il y a de bonnes nouvelles. Il y a eu quelques billets parlant de bulk_create
de mémoire. Le site billet indiqué ci-dessus est le plus susceptible d'avoir une solution qui sera bientôt mise en œuvre, mais il n'y a évidemment aucune garantie quant au moment où elle sera mise en œuvre ou si elle le sera un jour.
Il y a donc deux solutions possibles,
-
Attendez et voyez si ce patch arrive en production. Vous pouvez y contribuer en testant la solution proposée et en faisant part de vos réflexions et de vos problèmes à la communauté django. https://code.djangoproject.com/attachment/ticket/19527/bulk_create_and_create_schema_django_v1.5.1.patch
-
Remplacez / écrivez votre propre solution d'insertion en masse.
La solution la plus simple consiste probablement à attribuer manuellement des clés primaires. Cela dépend du cas particulier, mais parfois il suffit de commencer avec max(id)+1 de la table et d'attribuer des nombres qui s'incrémentent pour chaque objet. Cependant, si plusieurs clients peuvent insérer des enregistrements simultanément, un verrouillage peut être nécessaire.
Cela ne fonctionne pas dans la version de base de Django, mais il existe une fonction patch dans le bug tracker de Django qui permet à bulk_create de définir les clés primaires des objets créés.