במדריך הזה מוסבר איך להעביר נתונים מ-App Engine Blobstore ל-Cloud Storage.
Cloud Storage דומה ל-Blobstore ב-App Engine בכך שאפשר להשתמש ב-Cloud Storage כדי להציג אובייקטים גדולים של נתונים (blobs), כמו קובצי וידאו או תמונות, ולאפשר למשתמשים להעלות קובצי נתונים גדולים. אפשר לגשת אל App Engine Blobstore רק דרך חבילת השירותים מדור קודם של App Engine, אבל Cloud Storage הוא מוצר עצמאי שאפשר לגשת אליו דרך ספריות הלקוח ב-Cloud. Google CloudCloud Storage מציע לאפליקציה שלכם פתרון אחסון אובייקטים מודרני יותר, ומאפשר לכם לעבור ל-Cloud Run או לפלטפורמה אחרת לאירוח אפליקציות Google Cloud בהמשך.
ב Google Cloud פרויקטים שנוצרו אחרי נובמבר 2016, Blobstore משתמש בקטגוריות של Cloud Storage מאחורי הקלעים. כלומר, כשמעבירים את האפליקציה ל-Cloud Storage, כל האובייקטים וההרשאות הקיימים בקטגוריות הקיימות ב-Cloud Storage נשארים ללא שינוי. אפשר גם להתחיל לגשת לקטגוריות הקיימות האלה באמצעות ספריות הלקוח של Cloud Storage.
ההבדלים והדמיון העיקריים
Cloud Storage לא כולל את התלות והמגבלות הבאות של Blobstore:
- Blobstore API ל-Python 2 תלוי ב-webapp.
- Blobstore API ל-Python 3 משתמש במחלקות כלי עזר כדי להשתמש במטפלים ב-Blobstore.
- ב-Blobstore, אפשר להעלות עד 500 קבצים. אין הגבלה על מספר האובייקטים שאפשר ליצור בקטגוריה של Cloud Storage.
Cloud Storage לא תומך ב:
- מחלקות של תוכניות לטיפול ב-Blobstore
- אובייקטים ב-Blobstore
הדמיון בין Cloud Storage לבין Blobstore ב-App Engine:
- יכולת לקרוא ולכתוב אובייקטים גדולים של נתונים בסביבת זמן ריצה, וגם לאחסן ולספק אובייקטים סטטיים גדולים של נתונים, כמו סרטים, תמונות או תוכן סטטי אחר. גודל האובייקט המקסימלי ב-Cloud Storage הוא 5TiB.
- מאפשרת לכם לאחסן אובייקטים בקטגוריה של Cloud Storage.
- יש להם תוכנית בחינם.
לפני שמתחילים
- חשוב לעיין בתמחור ובמכסות של Cloud Storage ולהבין אותם:
- Cloud Storage הוא שירות בתשלום, ויש לו תמחור משלו לאחסון נתונים, שמבוסס על סוג האחסון (storage class) של הנתונים ועל המיקום של הקטגוריות.
- יש כמה הבדלים בין המכסות של Cloud Storage לבין המכסות והמגבלות של App Engine Blobstore, ויכול להיות שהם ישפיעו על מכסות הבקשות של App Engine.
- יש לכם אפליקציית App Engine קיימת ב-Python 2 או ב-Python 3 שמשתמשת ב-Blobstore.
- הדוגמאות במדריך הזה מציגות אפליקציה שמועברת ל-Cloud Storage באמצעות מסגרת Flask. שימו לב שאפשר להשתמש בכל מסגרת אינטרנט, כולל להישאר ב-
webapp2, כשמבצעים מיגרציה ל-Cloud Storage.
סקירה כללית
באופן כללי, תהליך ההעברה אל Cloud Storage מ-App Engine Blobstore מורכב מהשלבים הבאים:
- עדכון קובצי תצורה
- עדכון אפליקציית Python:
- עדכון מסגרת האינטרנט
- ייבוא והפעלה של Cloud Storage
- עדכון של הגורמים שמטפלים ב-Blobstore
- אופציונלי: אם אתם משתמשים ב-Cloud NDB או ב-App Engine NDB, אתם יכולים לעדכן את מודל הנתונים.
- בדיקה ופריסה של האפליקציה
עדכון קובצי תצורה
לפני שמשנים את קוד האפליקציה כדי לעבור מ-Blobstore ל-Cloud Storage, צריך לעדכן את קובצי ההגדרות כדי להשתמש בספריית Cloud Storage.
מעדכנים את הקובץ
app.yaml. פועלים לפי ההוראות שמתאימות לגרסת Python:Python 2
באפליקציות Python 2:
- מסירים את הקטע
handlersואת כל התלויות המיותרות של אפליקציות האינטרנט בקטעlibraries. - אם אתם משתמשים בספריות לקוח ב-Cloud, צריך להוסיף את הגרסאות העדכניות של הספריות
grpcioו-setuptools. - מוסיפים את הספרייה
sslכי היא נדרשת על ידי Cloud Storage.
קובץ
app.yamlלדוגמה עם השינויים שבוצעו:runtime: python27 threadsafe: yes api_version: 1 handlers: - url: /.* script: main.app libraries: - name: grpcio version: latest - name: setuptools version: latest - name: ssl version: latestPython 3
באפליקציות Python 3, מוחקים את כל השורות חוץ מהרכיב
runtime. לדוגמה:runtime: python310 # or another support versionסביבת זמן הריצה של Python 3 מתקינה ספריות באופן אוטומטי, כך שלא צריך לציין ספריות מובנות מסביבת זמן הריצה הקודמת של Python 2. אם האפליקציה שלכם ב-Python 3 משתמשת בשירותים אחרים שצורפו לגרסאות קודמות כשאתם מעבירים אותה ל-Cloud Storage, אל תשנו את הקובץ
app.yaml.- מסירים את הקטע
מעדכנים את הקובץ
requirements.txt. פועלים לפי ההוראות שמתאימות לגרסת Python:Python 2
מוסיפים את ספריות הלקוח של Cloud Storage לרשימת התלויות בקובץ
requirements.txt.google-cloud-storageלאחר מכן מריצים את הפקודה
pip install -t lib -r requirements.txtכדי לעדכן את רשימת הספריות שזמינות לאפליקציה.Python 3
מוסיפים את ספריות הלקוח של Cloud Storage לרשימת התלויות בקובץ
requirements.txt.google-cloud-storageApp Engine מתקין באופן אוטומטי את התלות האלה במהלך פריסת האפליקציה בסביבת זמן הריצה של Python 3, לכן צריך למחוק את התיקייה
libאם היא קיימת.באפליקציות Python 2, אם האפליקציה משתמשת בספריות מובנות או בספריות שהועתקו, צריך לציין את הנתיבים האלה בקובץ
appengine_config.py:import pkg_resources from google.appengine.ext import vendor # Set PATH to your libraries folder. PATH = 'lib' # Add libraries installed in the PATH folder. vendor.add(PATH) # Add libraries to pkg_resources working set to find the distribution. pkg_resources.working_set.add_entry(PATH)
עדכון אפליקציית Python
אחרי שמשנים את קובצי ההגדרות, מעדכנים את אפליקציית Python.
עדכון של מסגרת אינטרנט ב-Python 2
באפליקציות Python 2 שמשתמשות ב-framework webapp2, מומלץ להפסיק להשתמש ב-framework webapp2 המיושן. תאריך סיום התמיכה ב-Python 2 מופיע בלוח הזמנים של התמיכה בזמן ריצה.
אפשר להעביר את האתר ל-framework אחר לאינטרנט, כמו Flask, Django או WSGI. מכיוון ש-Cloud Storage לא כולל תלות ב-webapp2 ומטפלים ב-Blobstore לא נתמכים, אפשר למחוק או להחליף ספריות אחרות שקשורות לאפליקציות אינטרנט.
אם תבחרו להמשיך להשתמש ב-webapp2, שימו לב שהדוגמאות במדריך הזה משתמשות ב-Cloud Storage עם Flask.
אם אתם מתכננים להשתמש בשירותי Google Cloud בנוסף ל-Cloud Storage, או לקבל גישה לגרסאות העדכניות ביותר של זמן הריצה, כדאי לשדרג את האפליקציה לזמן הריצה של Python 3. מידע נוסף זמין במאמר סקירה כללית על העברה מ-Python 2 ל-Python 3.
ייבוא והפעלה של Cloud Storage
משנים את קובצי האפליקציה על ידי עדכון השורות של הייבוא וההפעלה:
מסירים הצהרות ייבוא של Blobstore, כמו אלה:
import webapp2 from google.appengine.ext import blobstore from google.appengine.ext.webapp import blobstore_handlersמוסיפים את הצהרות הייבוא של Cloud Storage ושל ספריות האימות של Google, כמו בדוגמה הבאה:
import io from flask import (Flask, abort, redirect, render_template, request, send_file, url_for) from google.cloud import storage import google.authצריך את ספריית האימות של Google כדי לקבל את אותו מזהה פרויקט ששימש ב-Blobstore עבור Cloud Storage. אם רלוונטי לאפליקציה, מייבאים ספריות אחרות כמו Cloud NBD.
יוצרים לקוח חדש ל-Cloud Storage ומציינים את הקטגוריה שבה נעשה שימוש ב-Blobstore. לדוגמה:
gcs_client = storage.Client() _, PROJECT_ID = google.auth.default() BUCKET = '%s.appspot.com' % PROJECT_IDב Google Cloud פרויקטים שנוצרו אחרי נובמבר 2016, מערכת Blobstore כותבת לקטגוריה של Cloud Storage שנקראת על שם כתובת ה-URL של האפליקציה, והיא פועלת לפי הפורמט
PROJECT_ID.appspot.com. משתמשים באימות של Google כדי לקבל את מזהה הפרויקט, וכך מציינים את קטגוריית Cloud Storage שמשמשת לאחסון של אובייקטים בינאריים ב-Blobstore.
עדכון של הגורמים שמטפלים ב-Blobstore
מכיוון ש-Cloud Storage לא תומך ב-handlers של העלאה והורדה של Blobstore, צריך להשתמש בשילוב של פונקציונליות של Cloud Storage, מודול של ספרייה רגילה, מסגרת האינטרנט וכלי Python כדי להעלות ולהוריד אובייקטים (blobs) ב-Cloud Storage.io
בדוגמה הבאה מוצג איך לעדכן את רכיבי ה-handler של Blobstore באמצעות Flask כמסגרת האינטרנט לדוגמה:
מחליפים את מחלקות הטיפול בהעלאות של Blobstore בפונקציית העלאה ב-Flask. פועלים לפי ההוראות שמתאימות לגרסת Python:
Python 2
Blobstore handlers ב-Python 2 הם מחלקות
webapp2כמו בדוגמה הבאה של Blobstore:class UploadHandler(blobstore_handlers.BlobstoreUploadHandler): 'Upload blob (POST) handler' def post(self): uploads = self.get_uploads() blob_id = uploads[0].key() if uploads else None store_visit(self.request.remote_addr, self.request.user_agent, blob_id) self.redirect('/', code=307) ... app = webapp2.WSGIApplication([ ('/', MainHandler), ('/upload', UploadHandler), ('/view/([^/]+)?', ViewBlobHandler), ], debug=True)כדי להשתמש ב-Cloud Storage:
- מחליפים את מחלקת ההעלאה של אפליקציית האינטרנט בפונקציית העלאה של Flask.
- מחליפים את ה-upload handler ואת הניתוב בשיטת Flask
POSTעם קישוט של ניתוב.
דוגמת קוד מעודכנת:
@app.route('/upload', methods=['POST']) def upload(): 'Upload blob (POST) handler' fname = None upload = request.files.get('file', None) if upload: fname = secure_filename(upload.filename) blob = gcs_client.bucket(BUCKET).blob(fname) blob.upload_from_file(upload, content_type=upload.content_type) store_visit(request.remote_addr, request.user_agent, fname) return redirect(url_for('root'), code=307)בדוגמת הקוד המעודכנת של Cloud Storage, האפליקציה מזהה עכשיו ארטיפקטים של אובייקטים לפי שם האובייקט (
fname) במקוםblob_id. ניתוב מתבצע גם בחלק התחתון של קובץ הבקשה.כדי לקבל את האובייקט שהועלה, מחליפים את השיטה
get_uploads()של Blobstore בשיטהrequest.files.get()של Flask. ב-Flask, אפשר להשתמש בשיטהsecure_filename()כדי לקבל שם בלי תווי נתיב, כמו/, עבור הקובץ, ולזהות את האובייקט באמצעותgcs_client.bucket(BUCKET).blob(fname)כדי לציין את שם הקטגוריה ואת שם האובייקט.הקריאה ל-Cloud Storage
upload_from_file()מבצעת את ההעלאה כמו שמוצג בדוגמה המעודכנת.Python 3
מחלקת הטיפול בהעלאות ב-Blobstore ל-Python 3 היא מחלקת כלי עזר שנדרש בה שימוש במילון WSGI
environכפרמטר קלט, כמו בדוגמה הבאה של Blobstore:class UploadHandler(blobstore.BlobstoreUploadHandler): 'Upload blob (POST) handler' def post(self): uploads = self.get_uploads(request.environ) if uploads: blob_id = uploads[0].key() store_visit(request.remote_addr, request.user_agent, blob_id) return redirect('/', code=307) ... @app.route('/upload', methods=['POST']) def upload(): """Upload handler called by blobstore when a blob is uploaded in the test.""" return UploadHandler().post()כדי להשתמש ב-Cloud Storage, מחליפים את השיטה
get_uploads(request.environ)של Blobstore בשיטהrequest.files.get()של Flask.דוגמת קוד מעודכנת:
@app.route('/upload', methods=['POST']) def upload(): 'Upload blob (POST) handler' fname = None upload = request.files.get('file', None) if upload: fname = secure_filename(upload.filename) blob = gcs_client.bucket(BUCKET).blob(fname) blob.upload_from_file(upload, content_type=upload.content_type) store_visit(request.remote_addr, request.user_agent, fname) return redirect(url_for('root'), code=307)בדוגמת הקוד המעודכנת של Cloud Storage, האפליקציה מזהה עכשיו ארטיפקטים של אובייקטים לפי שם האובייקט (
fname) במקוםblob_id. ניתוב מתבצע גם בחלק התחתון של קובץ הבקשה.כדי לקבל את האובייקט שהועלה, מחליפים את השיטה
get_uploads()של Blobstore בשיטהrequest.files.get()של Flask. ב-Flask, אפשר להשתמש בשיטהsecure_filename()כדי לקבל שם בלי תווי נתיב, כמו/, עבור הקובץ, ולזהות את האובייקט באמצעותgcs_client.bucket(BUCKET).blob(fname)כדי לציין את שם הקטגוריה ואת שם האובייקט.השיטה
upload_from_file()של Cloud Storage מבצעת את ההעלאה כמו בדוגמה המעודכנת.מחליפים את מחלקות ה-handler של ההורדות ב-Blobstore בפונקציית הורדה ב-Flask. פועלים לפי ההוראות שמתאימות לגרסת Python:
Python 2
בדוגמה הבאה של handler להורדה מוצג השימוש במחלקה
BlobstoreDownloadHandler, שמשתמשת ב-webapp2:class ViewBlobHandler(blobstore_handlers.BlobstoreDownloadHandler): 'view uploaded blob (GET) handler' def get(self, blob_key): self.send_blob(blob_key) if blobstore.get(blob_key) else self.error(404) ... app = webapp2.WSGIApplication([ ('/', MainHandler), ('/upload', UploadHandler), ('/view/([^/]+)?', ViewBlobHandler), ], debug=True)כדי להשתמש ב-Cloud Storage:
- מעדכנים את השיטה
send_blob()של Blobstore לשימוש בשיטהdownload_as_bytes()של Cloud Storage. - שינוי הניתוב מ-webapp2 ל-Flask.
דוגמת קוד מעודכנת:
@app.route('/view/<path:fname>') def view(fname): 'view uploaded blob (GET) handler' blob = gcs_client.bucket(BUCKET).blob(fname) try: media = blob.download_as_bytes() except exceptions.NotFound: abort(404) return send_file(io.BytesIO(media), mimetype=blob.content_type)בדוגמת הקוד המעודכנת של Cloud Storage, Flask מעטר את הנתיב בפונקציית Flask ומזהה את האובייקט באמצעות
'/view/<path:fname>'. Cloud Storage מזהה את האובייקטblobלפי שם האובייקט ושם הקטגוריה, ומשתמש בשיטהdownload_as_bytes()כדי להוריד את האובייקט כבייטים, במקום להשתמש בשיטהsend_blobמ-Blobstore. אם הארטיפקט לא נמצא, האפליקציה מחזירה שגיאת HTTP404.Python 3
בדומה ל-upload handler, המחלקה download handler ב-Blobstore ל-Python 3 היא מחלקה של כלי עזר, ונדרש שימוש במילון WSGI
environכפרמטר קלט, כמו בדוגמה הבאה של Blobstore:class ViewBlobHandler(blobstore.BlobstoreDownloadHandler): 'view uploaded blob (GET) handler' def get(self, blob_key): if not blobstore.get(blob_key): return "Photo key not found", 404 else: headers = self.send_blob(request.environ, blob_key) # Prevent Flask from setting a default content-type. # GAE sets it to a guessed type if the header is not set. headers['Content-Type'] = None return '', headers ... @app.route('/view/<blob_key>') def view_photo(blob_key): """View photo given a key.""" return ViewBlobHandler().get(blob_key)כדי להשתמש ב-Cloud Storage, צריך להחליף את השיטה
send_blob(request.environ, blob_key)של Blobstore בשיטהblob.download_as_bytes()של Cloud Storage.דוגמת קוד מעודכנת:
@app.route('/view/<path:fname>') def view(fname): 'view uploaded blob (GET) handler' blob = gcs_client.bucket(BUCKET).blob(fname) try: media = blob.download_as_bytes() except exceptions.NotFound: abort(404) return send_file(io.BytesIO(media), mimetype=blob.content_type)בדוגמת הקוד המעודכנת של Cloud Storage,
blob_keyמוחלף ב-fname, ו-Flask מזהה את האובייקט באמצעות כתובת ה-URL'/view/<path:fname>'. השיטהgcs_client.bucket(BUCKET).blob(fname)משמשת לאיתור שם הקובץ ושם הקטגוריה. השיטהdownload_as_bytes()של Cloud Storage מורידה את האובייקט כבייטים, במקום להשתמש בשיטהsend_blob()מ-Blobstore.- מעדכנים את השיטה
אם האפליקציה משתמשת ב-handler ראשי, צריך להחליף את המחלקה
MainHandlerבפונקציהroot()ב-Flask. פועלים לפי ההוראות שמתאימות לגרסת Python:Python 2
הדוגמה הבאה מראה איך להשתמש במחלקה
MainHandlerשל Blobstore:class MainHandler(BaseHandler): 'main application (GET/POST) handler' def get(self): self.render_response('index.html', upload_url=blobstore.create_upload_url('/upload')) def post(self): visits = fetch_visits(10) self.render_response('index.html', visits=visits) app = webapp2.WSGIApplication([ ('/', MainHandler), ('/upload', UploadHandler), ('/view/([^/]+)?', ViewBlobHandler), ], debug=True)כדי להשתמש ב-Cloud Storage:
- מסירים את הכיתה
MainHandler(BaseHandler), כי Flask מטפל בניתוב בשבילכם. - פישוט הקוד של Blobstore באמצעות Flask.
- מסירים את הניתוב של אפליקציית האינטרנט בסוף.
דוגמת קוד מעודכנת:
@app.route('/', methods=['GET', 'POST']) def root(): 'main application (GET/POST) handler' context = {} if request.method == 'GET': context['upload_url'] = url_for('upload') else: context['visits'] = fetch_visits(10) return render_template('index.html', **context)Python 3
אם השתמשתם ב-Flask, לא יהיה לכם מחלקה
MainHandler, אבל אם נעשה שימוש ב-blobstore, תצטרכו לעדכן את פונקציית השורש של Flask. בדוגמה הבאה נעשה שימוש בפונקציהblobstore.create_upload_url('/upload'):@app.route('/', methods=['GET', 'POST']) def root(): 'main application (GET/POST) handler' context = {} if request.method == 'GET': context['upload_url'] = blobstore.create_upload_url('/upload') else: context['visits'] = fetch_visits(10) return render_template('index.html', **context)כדי להשתמש ב-Cloud Storage, מחליפים את הפונקציה
blobstore.create_upload_url('/upload')בשיטהurl_for()של Flask כדי לקבל את כתובת ה-URL של הפונקציהupload().דוגמת קוד מעודכנת:
@app.route('/', methods=['GET', 'POST']) def root(): 'main application (GET/POST) handler' context = {} if request.method == 'GET': context['upload_url'] = url_for('upload') # Updated to use url_for else: context['visits'] = fetch_visits(10) return render_template('index.html', **context)- מסירים את הכיתה
בדיקה ופריסה של האפליקציה
שרת הפיתוח המקומי מאפשר לכם לבדוק שהאפליקציה פועלת, אבל לא תוכלו לבדוק את Cloud Storage עד שתפרסו גרסה חדשה, כי כל הבקשות ל-Cloud Storage צריכות להישלח דרך האינטרנט לקטגוריה בפועל ב-Cloud Storage. במאמר בדיקה ופריסה של האפליקציה מוסבר איך להריץ את האפליקציה באופן מקומי. לאחר מכן פורסים גרסה חדשה כדי לוודא שהאפליקציה נראית כמו קודם.
אפליקציות שמשתמשות ב-App Engine NDB או ב-Cloud NDB
אם האפליקציה שלכם משתמשת ב-App Engine NDB או ב-Cloud NDB, אתם צריכים לעדכן את מודל הנתונים של Datastore כדי לכלול מאפיינים שקשורים ל-Blobstore.
עדכון מודל הנתונים
מאחר שהמאפיינים BlobKey מ-NDB לא נתמכים ב-Cloud Storage, צריך לשנות את השורות שקשורות ל-Blobstore כדי להשתמש במקבילות מובנות מ-NDB, ממסגרות אינטרנט או ממקומות אחרים.
כדי לעדכן את מודל הנתונים:
מחפשים את השורות שמשתמשות ב-
BlobKeyבמודל הנתונים, כמו השורה הבאה:class Visit(ndb.Model): 'Visit entity registers visitor IP address & timestamp' visitor = ndb.StringProperty() timestamp = ndb.DateTimeProperty(auto_now_add=True) file_blob = ndb.BlobKeyProperty()מחליפים את
ndb.BlobKeyProperty()ב-ndb.StringProperty():class Visit(ndb.Model): 'Visit entity registers visitor IP address & timestamp' visitor = ndb.StringProperty() timestamp = ndb.DateTimeProperty(auto_now_add=True) file_blob = ndb.StringProperty() # Modified from ndb.BlobKeyProperty()אם אתם גם משדרגים מ-App Engine NDB ל-Cloud NDB במהלך ההעברה, כדאי לעיין במדריך להעברה ל-Cloud NDB כדי לקבל הנחיות לגבי שינוי קוד NDB כך שישתמש במנהלי הקשר של Python.
תאימות לאחור של מודל הנתונים של Datastore
בקטע הקודם, החלפת ndb.BlobKeyProperty ב-ndb.StringProperty גרמה לאפליקציה להיות לא תואמת לאחור, כלומר האפליקציה לא תוכל לעבד רשומות ישנות יותר שנוצרו על ידי Blobstore. אם אתם צריכים לשמור נתונים ישנים, אתם יכולים ליצור שדה נוסף לרשומות חדשות ב-Cloud Storage במקום לעדכן את השדה ndb.BlobKeyProperty, וליצור פונקציה לנרמול הנתונים.
מתוך הדוגמאות בקטעים הקודמים, מבצעים את השינויים הבאים:
כשמגדירים את מודל הנתונים, יוצרים שני שדות נפרדים של נכס. משתמשים במאפיין
file_blobכדי לזהות אובייקטים שנוצרו על ידי Blobstore, ובמאפייןfile_gcsכדי לזהות אובייקטים שנוצרו על ידי Cloud Storage:class Visit(ndb.Model): 'Visit entity registers visitor IP address & timestamp' visitor = ndb.StringProperty() timestamp = ndb.DateTimeProperty(auto_now_add=True) file_blob = ndb.BlobKeyProperty() # backwards-compatibility file_gcs = ndb.StringProperty()מחפשים את השורות שמתייחסות לביקורים חדשים, כמו השורות הבאות:
def store_visit(remote_addr, user_agent, upload_key): 'create new Visit entity in Datastore' with ds_client.context(): Visit(visitor='{}: {}'.format(remote_addr, user_agent), file_blob=upload_key).put()משנים את הקוד כך ש-
file_gcsישמש לערכים מהזמן האחרון. לדוגמה:def store_visit(remote_addr, user_agent, upload_key): 'create new Visit entity in Datastore' with ds_client.context(): Visit(visitor='{}: {}'.format(remote_addr, user_agent), file_gcs=upload_key).put() # change file_blob to file_gcs for new requestsיוצרים פונקציה חדשה לנרמול הנתונים. בדוגמה הבאה מוצג השימוש ב-ETL (חילוץ, טרנספורמציה וטעינה) כדי לבצע לולאה בכל הביקורים, ולקחת את נתוני המבקר וחותמת הזמן כדי לבדוק אם קיימים
file_gcsאוfile_gcs:def etl_visits(visits): return [{ 'visitor': v.visitor, 'timestamp': v.timestamp, 'file_blob': v.file_gcs if hasattr(v, 'file_gcs') \ and v.file_gcs else v.file_blob } for v in visits]מוצאים את השורה שמפנה לפונקציה
fetch_visits():@app.route('/', methods=['GET', 'POST']) def root(): 'main application (GET/POST) handler' context = {} if request.method == 'GET': context['upload_url'] = url_for('upload') else: context['visits'] = fetch_visits(10) return render_template('index.html', **context)עוטפים את
fetch_visits()בפונקציהetl_visits(), לדוגמה:@app.route('/', methods=['GET', 'POST']) def root(): 'main application (GET/POST) handler' context = {} if request.method == 'GET': context['upload_url'] = url_for('upload') else: context['visits'] = etl_visits(fetch_visits(10)) # etl_visits wraps around fetch_visits return render_template('index.html', **context)
דוגמאות
- כדי לראות דוגמה להעברת אפליקציית Python 2 ל-Cloud Storage, אפשר להשוות בין דוגמת הקוד של Blobstore ל-Python 2 לבין דוגמת הקוד של Cloud Storage ב-GitHub.
- כדי לראות דוגמה להעברת אפליקציית Python 3 ל-Cloud Storage, אפשר להשוות בין דוגמת הקוד של Blobstore ל-Python 3 לבין דוגמת הקוד של Cloud Storage ב-GitHub.
המאמרים הבאים
- מדריך מעשי בנושא זמין במאמר העברה מ-App Engine Blobstore ל-Cloud Storage codelab ל-Python.
- איך מאחסנים ומציגים קבצים סטטיים מ-Cloud Storage
- פרטים נוספים זמינים במסמכי העזרה של Cloud Storage.