2011-07-07 4 views
10

J'utilise django staticfiles + django-storages et Amazon S3 pour héberger mes données. Tout fonctionne bien sauf que chaque fois que je cours manage.py collectstatic la commande télécharge tous les fichiers sur le serveur.Django StaticFiles et Amazon S3: Comment détecter les fichiers modifiés?

Il semble que la commande de gestion compare les horodatages de Storage.modified_time() qui ne sont pas implémentés dans le stockage S3 à partir de django-stockages.

Comment les gars déterminent-ils si un fichier S3 a été modifié?

Je pourrais stocker les chemins de fichiers et les dernières données modifiées dans ma base de données. Ou existe-t-il un moyen facile d'extraire les dernières données modifiées d'Amazon?

Une autre option: il semble que je puisse assigner des métadonnées arbitraires avec python-boto où je pourrais mettre la date modifiée locale quand je télécharge la première fois.

De toute façon, il semble que ce soit un problème commun donc je voudrais demander quelle solution les autres ont utilisée. Merci!

Répondre

10

La dernière version de django-storages (1.1.3) gère la détection de modification de fichier via S3 Boto.

pip install django-storages et vous êtes bien maintenant :) Je dois aimer l'open source!

Mise à jour: réglez l'option AWS_PRELOAD_METADATA sur True dans votre fichier de paramètres pour avoir des synchronisations très rapides si vous utilisez la classe S3Boto. Si vous utilisez son S3, utilisez sa classe PreloadedS3.


Mise à jour 2: Il est toujours extrêmement lent d'exécuter la commande.


Mise à jour 3: I forked the django-storages repository pour résoudre le problème et a ajouté une demande de traction.

Le problème est dans la méthode modified_time où la valeur de repli est appelée même si elle n'est pas utilisée. Je me suis déplacé le repli à un bloc if à exécuter que si get retours None

entry = self.entries.get(name, self.bucket.get_key(self._encode_name(name))) 

devraient être

entry = self.entries.get(name) 
    if entry is None: 
     entry = self.bucket.get_key(self._encode_name(name)) 

Maintenant, la différence de performance est de < .5s pour 1000 demandes de 100s


Mise à jour 4:

Pour la synchronisation de fichiers 10k +, je crois que boto doit faire plusieurs requêtes puisque S3 pagine les résultats provoquant un temps de synchronisation de 5-10 secondes. Cela ne fera qu'empirer car nous recevons plus de fichiers. Je pense qu'une solution est d'avoir une commande de gestion personnalisée ou django-storages où un fichier est stocké sur S3 qui a les métadonnées de tous les autres fichiers, qui est mis à jour chaque fois qu'un fichier est mis à jour via la commande collectstatic.

Il ne détectera pas les fichiers téléchargés par d'autres moyens, mais n'aura aucune importance si le seul point d'entrée est la commande de gestion.

+0

Comment utilisez-vous la méthode modified_time? Exécuter uniquement ./manage.py collecstatic, ne fonctionne pas pour moi. Il utilise la méthode _save de botos3 pour enregistrer les fichiers, mais il ne vérifie pas à tout moment si le fichier est nouveau ou non. Quelle est ta solution? – duduklein

+0

Cela semble ne plus être vrai: python-dateutil> 2.1 supporte maintenant Python 2 et 3 dans une base de code partagée et python-dateutil == 2.1 fonctionne bien pour moi avec botos3. –

+0

Hey Yuji; Je cours dans ce même problème (collectstatics lent avec S3Boto avec plusieurs milliers de fichiers). Je me demande où vous vous en êtes rendu compte. Pourriez-vous résumer vos meilleures recommandations actuelles pour optimiser ce processus, puisque vous avez clairement passé beaucoup de temps à résoudre ce problème? –

0

J'ai répondu à la même question ici https://stackoverflow.com/a/17528513/1220706. Découvrez https://github.com/FundedByMe/collectfast. Il s'agit d'une application Django connectable qui met en cache l'ETag des fichiers S3 distants et compare la somme de contrôle mise en cache au lieu d'effectuer une recherche à chaque fois. Suivez les instructions d'installation et exécutez collectstatic comme d'habitude. Il m'a fallu d'une moyenne d'environ 1m30s à environ 10s par déploiement.

Questions connexes