Alembic מכונת הזמן לשירות מסד הנתונים בפרויקט ה-FastApi שלך

מחבר:
בתאריך:

Avoid creative improvisations inside boilerplate code.

בואו נהיה כנים. לעדכן את מסד הנתונים באופן ידני עם שאילתות `ALTER TABLE` זה מתכון בטוח לשבירת האפליקציה שלך, במיוחד כשעובדים בצוות או מעלים גרסה לייצור.

Alembic היא ה-Git של מסד הנתונים שלך. היא מאפשרת לך לתעד כל שינוי בקוד, לחזור אחורה בזמן אם משהו השתבש, ולוודא שכל סביבות העבודה (פיתוח, בדיקות ופרודקשן) מסונכרנות לחלוטין. במדריך הזה תלמד איך להקים את "מכונת הזמן" הזו בתוך פרויקט FastAPI מאפס ועד לניהול שוטף.

על פי התיעוד הרשמי Python Alembic הוא כלי לביצוע migrations של מסדי נתונים עבור SQLAlchemy. הוא מספק מערכת לניהול שינויים בסכימת מסד הנתונים באופן מובנה ומבוקר גרסאות, בדומה לאופן שבו כלים כמו Git עובדים.

בוא נלמד איך הוא עובד הלכה למעשה.

 

0. סביבת העבודה

ההנחה היא שאתה עובד בתוך סביבת פייתון. אם אתה עובד על המחשב האישי מומלץ ליצור סביבה וירטואלית של פייתון ולעבוד בתוכה כדי שתוכל לעבוד בבטחה בלי להתנגש עם פרויקטים אחרים.

 הנחה נוספת היא שאתה עובד על פרויקט של FastApi. זה אומנם לא הכרחי אבל מאוד מומלץ כדי שתוכל לעקוב אחר הנעשה במדריך.

$ pip install fastapi uvicorn[standard]

יש להוסיף לתיקיית השורש של הפרויקט את התיקייה core בתוכה ישב הקובץ models.py, בתוכו ירשמו המודלים שישרתו את האפליקציה הפשוטה שלנו.

root/
    core/
        main.py

 

הקובץ main.py מכיל את הקוד הבסיסי הבא:

# Core package
import uvicorn
from fastapi import FastAPI

# import DB
from database import get_db

# Init app
app = FastAPI(title="Learn Alembic")

# Define the first static route
@app.get('/')
def index():
	return {'hello': 'fastapi'}

# Run the application
if __name__ == '__main__':
	uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True, access_log=False)

כיוון שהפרויקט עובד מול מסד נתונים MySQL יש להתקין את התלות הבאה:

$ pip install mysql-connector-python

כמו כן, יש ליצור מסד נתונים, משתמש במסד הנתונים ופרטי גישה. במדריך אני משתמש בפרטים הבאים של מסד הנתונים:

DB_USERNAME=app_admin
DB_PASSWORD=safer_than_12345
DB_NAME=app_db
  • פרטי הגישה כלל אינם בטוחים. שים לב לא להשתמש בהם בטעות בפרויקט החשוף לעולם החיצון.

קוד ה-MySQL להלן יכול לעזור לך בייסוד מסד הנתונים והגדרת המשתמש:

-- Create the database
CREATE DATABASE IF NOT EXISTS app_db;

-- Create the user and set the password
CREATE USER 'app_admin'@'localhost' IDENTIFIED BY 'safer_than_12345';

-- Grant all privileges on the database to the new user
GRANT ALL PRIVILEGES ON app_db.* TO 'app_admin'@'localhost';

-- Apply the changes
FLUSH PRIVILEGES;

להלן מבנה הקבצים והתיקיות של האפליקציה רק כדי לסדר את הראש:

├── alembic.ini
├── core
│   └── models.py
├── database.py
├── main.py
├── migrations
│   ├── env.py
│   ├── script.py.mako
│   └── versions
│       ├── <hash1>_initial_schema.py
│       ├── <hash2>_create_users_table.py
│       └── <hash1>_add_last_login_and_verification_code_to_.py
└── settings.py
  • את הקבצים והתיקיות ניצור בהמשך המדריך צעד אחר צעד כך שלא צריך להוסיף מראש.

 

1. התקנת Alembic

בתוך סביבת העבודה, בשביל להתקין את Alembic הקלד את הפקודה הבאה לתוך הטרמינל:

$ pip install alembic

 

Python Alembic is a lightweight database migration tool for SQLAlchemy, the popular Python database toolkit

2. אתחול Alembic בתוך הפרויקט

אתחל את Alembic ברמת הפרויקט בתוך תיקיית השורש של הפרויקט, היכן ש-main.py:

$ alembic init migrations
הרצת הפקודה יוצרת את מבנה הקבצים הבא:
migrations/
    env.py
    script.py.mako
    versions/
alembic.ini

 

3. חיבור Alembic למסד הנתונים

בשלב זה, יש להוסיף לתיקיית השורש את הקובץ database.py דרכו תעשה ההתקשרות עם מסד הנתונים:

database.py

# database.py

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, declarative_base
import settings

# MySQL connection string
SQLALCHEMY_DATABASE_URL = (
    f"mysql+mysqlconnector: / / {settings.DATABASE['username']}:"
    f"{settings.DATABASE['password']}@localhost/"
    f"{settings.DATABASE['db_name']}"
)

# Engine
engine = create_engine(
    SQLALCHEMY_DATABASE_URL,
    pool_pre_ping=True,     # Prevent MySQL "connection lost" crashes
    connect_args={}         # Required for mysqlconnector, left empty
)

# Session
SessionLocal = sessionmaker(
    autocommit=False,
    autoflush=False,
    bind=engine
)

# Base model
Base = declarative_base()


# Dependency
def get_db():
    db = SessionLocal()
    try:
        yield db
    finally:
        db.close()

את המידע הרגיש אין שומרים בתיקיית הפרויקט. במקום זאת, מאחסנים אותו בקובץ מאובטח. אפשר על המחשב.

הקובץ צריך לכלול את פרטי הגישה למסד הנתונים. לדוגמה, בתוך הקובץ:

/path/to/app_secrets.env

DB_USERNAME=app_admin
DB_PASSWORD=safer_than_12345
DB_NAME=app_db
  • הקובץ עשוי לכלול מידע נוסף שלא רוצים שיפול לידיים הלא נכונות. לדוגמה, כאשר תעלה את תיקיית הפרויקט ל-GitHub.

לאחר שעורכים את הקובץ, מטעמי אבטחה, יש לאפשר גישה לאפליקציה בלבד:

$ chmod 600 /path/to/app_secrets.env
$ chown admin:admin /path/to/app_secrets.env
  • לצורך המדריך, שם המשתמש והקבוצה שניהם admin. עליך לבדוק ולשנות בהתאם לפרטי הבעלות על תיקיית הפרויקט במקרה שלך.

בתוך תיקיית הפרויקט מייבאים את המידע לתוך קובץ settings.py, אותו יש ליצור (בדרך כלל בתיקיית השורש של הפרויקט), שם תגדיר את פרטי הגישה למסד הנתונים באופן הבא:

settings.py

# settings.py


import os
from pathlib import Path
from dotenv import load_dotenv


# Absolute path to the secret file
DOTENV_PATH = Path.home() / "secrets" / "app_secrets.env"


# Load the secrets
load_dotenv(dotenv_path=DOTENV_PATH)


DATABASE = {
   'username': os.getenv("DB_USERNAME"),
   'password': os.getenv("DB_PASSWORD"),
   'db_name': os.getenv("DB_NAME")
}


DATABASE_URL = f"mysql+mysqlconnector: / / {DATABASE['username']}:{DATABASE['password']}@localhost/{DATABASE['db_name']}"

עורכים את הקובץ migrations/env.py באופן המאפשר ל-Alembic לעבוד ישירות עם מסד הנתונים של הפרויקט כשאת פרטי הגישה מספק הקובץ settings.py:

migrations/env.py

from logging.config import fileConfig
from sqlalchemy import engine_from_config, pool
from alembic import context

# --- Load project modules ---
import settings  # <-- add this
from database import Base  # <-- your project Base, make sure it fits your project
from core import models     # <-- ensure models are imported so Alembic sees them

# Load Alembic config
config = context.config

# Override DB URL from settings.py
# This ensures no secrets in alembic.ini and same DB as your app
config.set_main_option("sqlalchemy.url", settings.DATABASE_URL)

# Logging
if config.config_file_name is not None:
    fileConfig(config.config_file_name)

target_metadata = Base.metadata
  • דבר זה מבטיח ש-Alembic ישתמש במסד הנתונים של האפליקציה.
  • from core import models מניח שכל המודלים מרוכזים בקובץ אחד. אם זה לא המצב אצלך עליך לשנות את ההגדרות מהיכן לייבא בהתאם.

שים לב:

בשלב זה, פרטי הגישה למסד הנתונים יילקחו מ- migrations/env.py. כדי שלא תתבלבל בעתיד ותחשוב שמקור הנתונים הוא בקובץ alembic.ini כדאי שתערוך את הקובץ alembic.ini המצוי בתיקיית השורש, ותכניס את השורה הבאה להערה (אפשר להוסיף כמה דברי הסבר שאתה העתידי יוכל להודות לך עליהם):

alembic.ini

# ATTENTION: Real database URL is loaded from settings.py in migrations/env.py
# This file does NOT contain the actual database connection
# See migrations/env.py for the actual configuration

# sqlalchemy.url = mysql+pymysql/user:pass@host/dbname  # COMMENTED INTENTIONALLY
  • כיוון שהמידע על החיבור האמיתי מגיע מהקובץ settings.py חשוב לסמן לעצמך באופן ברור שמקור הנתונים אינו בקובץ ini

 

4. ודא ש-database.py מגדיר את ה-Base הנכון

בשלב זה, עליך לוודא שאתה מייבא את Base כתלות לקובץ models.py:

core/models.py

from database import Base

ועכשיו כל המודלים צריכים לרשת את Base.

לדוגמה:

core/models.py

# Example of a model.
# class User(Base):
#    __tablename__ = "users"

 

5. צעד אופציונלי יצירת Migration ראשוני הכולל עדכון Alembic במצב העכשווי של מסד הנתונים

במידה ואתחלת את Alembic בתוך פרויקט שיש לו כבר טבלאות במסד הנתונים אתה עלול להיתקל בבעיה שהרצת Alembic תגרום להופעת שגיאה. כדי למנוע את השגיאה הרץ הפקודה:

$ alembic revision --autogenerate -m "Initial schema"

הטרמינל יציג הודעות לגבי תהליך ההגירה. משהו דומה לזה:

INFO  [alembic.runtime.migration] Context impl MySQLImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.autogenerate.compare] Detected removed table 'workers'
  Generating /migrations/versions/201d4536370e_initial_schema.py ...  done

התהליך ייצר קובץ migration ראשוני הכולל את הסכימה הנוכחית שלך עם כל הטבלאות הקיימות במסד הנתונים.

פתח את הקובץ:

migrations/versions/<hash>_initial_schema.py

וודא את נכונותו ביחס לסכימה הקיימת במסד הנתונים.

שים לב! בשלב זה אל תריץ את הפקודה:

$ alembic upgrade head

כדי שלא תגרום ל-Alembic לנסות להוסיף למסד הנתונים את הטבלאות שכבר קיימות בו. דבר שיגרום לשגיאה.

במקום זאת, עשה stamp שמונע את הרצת ה-migration הנוכחי:

$ alembic stamp head

דבר שמסמן את ה-migration הנוכחי כ- "already applied", ועל כן אין לבצעו שנית.

 

6. הוספת migrations נוספים באופן הרגיל

הקוד בחלק זה של המדריך מציג הוספה ועדכון של migrations באמצעות דוגמה של מודל Users.

הקובץ models.py מכיל את המודלים שאיתם רוצים לעבוד. נערוך אותו כדי להוסיף את המודל החדש User:

models.py

from database import Base
from sqlalchemy import Boolean, Column, DateTime, Integer, String, func


class User(Base):
    __tablename__ = "users"

    id = Column(Integer, primary_key=True, index=True)
    email = Column(String(80), unique=True, nullable=False)
    username = Column(String(80))
    password = Column(String(256), nullable=False)
    picture = Column(String(120), default="default.png")

    active = Column(Boolean, default=True)
    is_verified = Column(Boolean, default=False)

    created_at = Column(DateTime(timezone=True), server_default=func.now())
    updated_at = Column(DateTime(timezone=True), onupdate=func.now())

הפיכת הקלאס `User` לטבלה במסד הנתונים באמצעות Alembic כרוכה בביצוע שני שלבים:

  1. יצירת סקריפט migration
  2. הזנה למסד הנתונים

אתה יכול לגשת לשלב זה בבטחה רק אחרי שקינפגת את הקבצים alembic.ini ו-migrations/env.py כך שהם מצביעים על מסד הנתונים ואחרי ש-Base.metadata הוגדר כהלכה (ראה סעיף 3 לעיל).

הפקודה revision --autogenerate אותה אתה מריץ בטרמינל בוחנת את המצב הנוכחי של מסד הנתונים ומשווה עם המודלים המוגדרים אצלך בקוד, דוגמת Users, ומזה מסיקה אילו שינויים צריך לערוך במסד הנתונים:

$ alembic revision --autogenerate -m "Create users table"
  • אחרי -m אתה מוסיף תיאור קצר של ה-migration

התוצאה של הרצת הפקודה היא יצירת קובץ פייתון חדש שישב בתיקייה migrations/versions בצירוף האש ייחודי. לדוגמה migrations/versions/<hash>_add_users_table.py. הקובץ מכיל פונקציות upgrade() ו-downgrade() עם הוראות לאופרציות ספציפיות של SQLAlchemy המיועדות ליצירת הטבלה "users" במסד הנתונים ואף להסרתה, אם יהיה בכך צורך בעתיד.

בשלב זה, כדאי לפתוח את קובץ הפייתון החדש שנוצר ב-migrations/versions/ כדי לוודא שהפקודות לשינוי מסד הנתונים נראות תקינות עוד לפני הפעלתן. הקובץ צריך להכיל קוד ליצירת הטבלה, האילוצים, אינדקסים ומפתחות זרים.

אחרי שווידאת שהסקריפט עושה את מה שאתה מצפה, עליך להריץ את הפקודה upgrade לביצוע בפועל של הזנת סכימת הטבלה למסד הנתונים:

$ alembic upgrade head
  • אחרי הרצת הפקודה, הטבלה "users" צריכה להתווסף אוטומטית למסד הנתונים, דבר שכדאי לך לוודא.

מבט על תהליך ה-migration:

 

התהליך בן 5 השלבים להלן יחזור על עצמו בכל פעם שתרצה לערוך שינוי סכמה בעתיד אז גזור ושמור או לפחות קרא בתשומת לב מלאה:

  1. עריכת המודלים של SQLAlchemy (קובץ models של FastApi)
  2. יצירת סקריפט migration:

    $ alembic revision --autogenerate -m "..."
  3. בדיקת תקינות סקריפט ה-migration.

  4. אינטגרציה של השינויים עם מסד הנתונים:

    $ alembic upgrade head
  5. וידוא מול מסד הנתונים שהשינויים אכן בוצעו.

 

7. איך לעדכן Model ?

נוסיף שני שדות נוספים לקלאס `User` אשר יושב בתוך הקובץ models של FastApi:

models.py

last_login = Column(DateTime, nullable=True)
verification_code = Column(String(20), nullable=True)

בשלב זה:

  1. יוצרים סקריפט migration
  2. מפקידים למסד הנתונים

לצורך יצירת סקריפט migration מריצים הפקודה:

$ alembic revision --autogenerate -m "Add last_login and verification_code to users"

Alembic יסרוק את המטא-דאטה, ישווה אותו למסד הנתונים וייצור את הסקריפט אותו תמצא בקובץ:

migrations/versions/<hash>_add_last_login_and_verification_code.py

אל תמהר להאמין לכל כלי המבטיח לך אוטומציה. תקפיד לעבור על המידע בתוך הקובץ, שעשוי להראות כך:

def upgrade():
    op.add_column('users', sa.Column('last_login', sa.DateTime(), nullable=True))
    op.add_column('users', sa.Column('verification_code', sa.String(length=20), nullable=True))

def downgrade():
    op.drop_column('users', 'verification_code')
    op.drop_column('users', 'last_login')

וודא:

  • ששם הטבלה נכון
  • סוגי השדות תואמים את דרישות המודל
  • לא נוספו שינויים שאינך רוצה
  • לא חסרים שינויים שאתה מעוניין לערוך

רק לאחר שווידאת את הסקריפט, הרץ את הפקודה לאינטגרציה של השינויים לתוך מסד הנתונים:

$ alembic upgrade head
  • וודא שמסד הנתונים אכן עודכן כצפוי.

8. איך לעשות undo ל-migrations?

בשלב זה, יש לנקוט בזהירות כי מוטב להיזהר מלהצטער, וגם לפני שמבטלים תמיד מגבים.

 

לצורך ביטול ה-migration האחרון בפרויקט הרץ הפקודה:

$ alembic downgrade -1
  • פקודה זו מריצה את פונקצית downgrade() בסקריפט ה-migration האחרון ומעדכנת את טבלת alembic_version במסד הנתונים לגרסה האחת לפני אחרונה.

כדי לשנמך עד ל- migration ספציפי (כולל), יש להריץ הפקודה:

$ alembic downgrade <target_revision_id>

כדי למצוא את ה-`id` של ה-migration שאתה רוצה לשנמך הרץ הפקודה:

$ alembic history

לאחר מכן, השתמש במזהה הגרסה הרצוי כיעד עבור פקודת ה-downgrade. הפקודה תפעיל את כל פונקציות ה-downgrade() הדרושות עד שמסד הנתונים יגיע לגרסה הספציפית הזו.

כדי לבטל את כל ה-migrations ולחזור למצב הבסיסי, מריצים הפקודה:

$ alembic downgrade base
  • פקודה זו מפעילה את כל פונקציות downgrade() בפרויקט שלך, משמיטה את הטבלה alembic_version , ובסופו של דבר משאירה את סכמת מסד הנתונים במצב ריק.

 

9. נקודות שכדאי לשים אליהם לב כי אין חכם כבעל ניסיון

9.1 : Alembic לא מזהה את המודלים שלי כשאני מריץ את הפקודה --autogenerate

הבעיה:

שכחת ליבא את המודלים לתוך migrations/env.py.

התיקון:

migrations/env.py

from database import Base # <-- your project Base, make sure it fits your project
from core import models # <-- ensure models are imported so Alembic sees them
  • Alembic טוען רק את מה שהוא מייבא. אם מודלים אינם מיובאים, לא ניתן להשתמש בהם לצורך migrations.

 

9.2: Alembic מנסה למחוק טבלאות או ליצור מחדש טבלאות שכבר קיימות

הבעיה:

אתחלת את Alembic לאחר שטבלאות כבר נוצרו באופן ידני.

התיקון:

אל תריץ את הפקודה `upgrade head`, במקום זאת הרץ :

$ alembic stamp head

מה שאומר ל-Alembic: "מצב מסד הנתונים הנוכחי הוא המצב העדכני ביותר של ה-migrations. אל תנסה לשנות את הקיים."

 

9.3: העתקתי תיקיית פרויקט, ו-Alembic מתנהג בצורה מוזרה או אינו מוציא לפועל migrations

הבעיה:

אתחלת את Alembic לאחר שטבלאות כבר קיימות במסד הנתונים.

התיקון:

שים לב! שלב זה כרוך בביצוע שינוי שאינו ניתן לשחזור אלא אם לפני מחיקת מסד הנתונים והקבצים טרחת לגבות.

  1. הסר את קבצי ה-migration הישנים:

    $ rm -rf migrations/versions/*
  2. נקה את טבלת `alembic_version` במסד הנתונים:

    MySQL > TRUNCATE alembic_version;
  3. אתחל את ה-migrations על נקי:

    $ alembic revision --autogenerate -m "Initial schema"
    $ alembic stamp head

 

9.4 : הרצת --autogenerate יוצרת קבצי migration ריקים

הבעיה:

המודלים שלך אינם קשורים לאותו Base metadata בו משתמש Alembic.

התיקון:

וודא ההגדרה:

# database.py
Base = declarative_base()

שכל המודלים יורשים את ה-Base:

class User(Base):
    __tablename__ = "users"

וגם וודא בקובץ env.py:

# migrations/env.py
target_metadata = Base.metadata

 

9.5 : עדכנתי את המודל אבל Alembic לא מזהה את השינוי

סיבות נפוצות:

  • ערכת קובץ שגוי (למשל, models.py משוכפל בתיקייה אחרת)
  • אולי שכחת ייבוא ל-env.py
  • ישנה שגיאה בהקלדת `__tablename__` במודל
  • שימוש בערכי ברירת מחדל של SQLAlchemy ש-Alembic לא יכול לזהות

תיקון:

  • הפעלה מחדש של פקודות Alembic
  • בדיקה נוספת של ייבוא תלויות ב-env.py
  • ודא שאין שגיאה בשם הטבלה במודל
  • לפעמים אין ברירה וצריך לערוך ידנית את קובץ ה-migration

 

9.6: הפעלתי שינמוך downgrade של migration ולא קיבלתי את התוצאות הרצויות

סיבה:

  • קובץ migration שגוי

תיקון:

  • ודא ש-downgrade() עושה בדיוק את ההפך מ-upgrade().

* יוצ"ד יחיד הוא baseline migration שיכול להיות לו downgrade() ריק

 

9.7: השדות במסד הנתונים, דוגמת JSON או חותמות זמן, נראים שגויים

סיבה:

לפעמים Alembic מזהה דיאלקטים של SQL באופן שגוי.

תיקון:

1. יבוא מפורש של הדיאלקט בראש הקובץ:

migrations/versions/<hash>_schema.py

from sqlalchemy.dialects import mysql

2. ציון מפורש של סוג השדה עבור סוגים שידוע שעושים בעיות:

from sqlalchemy.dialects import mysql

def upgrade():
    op.add_column('my_table', sa.Column('data', sa.JSON()))  # Explicit sa.JSON
    op.add_column('my_table', sa.Column('created_at', sa.DateTime(timezone=True)))  # Add timezone
    op.add_column('my_table', sa.Column('label', sa.String(length=255)))  # Explicit length

 

9.8: שיניתי את מסד הנתונים באופן ידני ועכשיו ה-migrations נשברו

זו אחת הטעויות הגדולות ביותר.

תיקון:

  • לעולם אל תעדכן את מסד הנתונים באופן ידני. הדרך היחידה שעובדת היא הקפדה על migrations.
  • אם כבר עשית את זה עליך להחזיר את מסד הנתונים למצב התואם את היסטוריית ה-migrations אליבא דAlembic.
  • או צור העברה "מזויפת" שתגרום ל-Alembic להתאים עצמו למסד הנתונים הקיים, באמצעות הרצת הפקודה:
$ alembic stamp head

ואם התיקון לא מצליח:

  1. תבדוק את הטבלה `alembic_version` במסד הנתונים. אתה מצפה לראות בה ערך אחד בלבד.
  2. האם הערך תואם את שם קובץ ה-migration האחרון שלך.
  3. אם אתה רואה בלאגן אז תעשה את מה שכתוב ב-9.3 (לפני מחיקת מסד הנתונים והקבצים עליך לוודא שהכל מגובה).

 

9.9 מסד הנתונים השתנה אבל האפליקציה שלי עדיין משתמשת בסכמה הישנה

סיבות אפשריות:

  • אם אתה משתמש במסד הנתונים הנכון
  • אז תבדוק אם שכחת להריץ: alembic upgrade head

 

מדריכים נוספים בסדרת הפייתון באתר רשתטק שעשויים לעניין אותך

אפליקצית אינטרנט עם FastApi - הקמת מסד הנתונים

FastApi - לעבוד עם מסד נתונים - ORM ואלכימיה

קישור אובייקטים של מסד הנתונים כשעובדים עם FastApi - קצר ולעניין

 

לכל המדריכים בסדרה ללימוד פייתון

 

אהבתם? לא אהבתם? דרגו!

0 הצבעות, ממוצע 0 מתוך 5 כוכבים

 

 

המדריכים באתר עוסקים בנושאי תכנות ופיתוח אישי. הקוד שמוצג משמש להדגמה ולצרכי לימוד. התוכן והקוד המוצגים באתר נבדקו בקפידה ונמצאו תקינים. אבל ייתכן ששימוש במערכות שונות, דוגמת דפדפן או מערכת הפעלה שונה ולאור השינויים הטכנולוגיים התכופים בעולם שבו אנו חיים יגרום לתוצאות שונות מהמצופה. בכל מקרה, אין בעל האתר נושא באחריות לכל שיבוש או שימוש לא אחראי בתכנים הלימודיים באתר.

למרות האמור לעיל, ומתוך רצון טוב, אם נתקלת בקשיים ביישום הקוד באתר מפאת מה שנראה לך כשגיאה או כחוסר עקביות נא להשאיר תגובה עם פירוט הבעיה באזור התגובות בתחתית המדריכים. זה יכול לעזור למשתמשים אחרים שנתקלו באותה בעיה ואם אני רואה שהבעיה עקרונית אני עשוי לערוך התאמה במדריך או להסיר אותו כדי להימנע מהטעיית הציבור.

שימו לב! הסקריפטים במדריכים מיועדים למטרות לימוד בלבד. כשאתם עובדים על הפרויקטים שלכם אתם צריכים להשתמש בספריות וסביבות פיתוח מוכחות, מהירות ובטוחות.

המשתמש באתר צריך להיות מודע לכך שאם וכאשר הוא מפתח קוד בשביל פרויקט הוא חייב לשים לב ולהשתמש בסביבת הפיתוח המתאימה ביותר, הבטוחה ביותר, היעילה ביותר וכמובן שהוא צריך לבדוק את הקוד בהיבטים של יעילות ואבטחה. מי אמר שלהיות מפתח זו עבודה קלה ?

השימוש שלך באתר מהווה ראייה להסכמתך עם הכללים והתקנות שנוסחו בהסכם תנאי השימוש.

הוסף תגובה חדשה

 

 

ענה על השאלה הפשוטה הבאה כתנאי להוספת תגובה:

איך קוראים בעברית לצ`ופצ`יק של הקומקום?