FLASK-SQLALCHEMY(1) Flask-SQLAlchemy FLASK-SQLALCHEMY(1)

flask-sqlalchemy - افزونه‌ی Flask برای پشتیبانی از SQLAlchemy [تصویر]

افزونه‌ی Flask-SQLAlchemy یک افزونه برای Flask https://flask.palletsprojects.com است که پشتیبانی از SQLAlchemy https://www.sqlalchemy.org را به برنامه‌ی شما اضافه می‌کند. این افزونه با راه‌اندازی اشیاء و الگوهای رایج برای استفاده از آن‌ها، مانند نشست (session) متصل به هر درخواست وب، مدل‌ها (models) و موتورها (engines)، استفاده از SQLAlchemy را به همراه Flask ساده‌تر می‌کند.

افزونه‌ی Flask-SQLAlchemy نحوه‌ی کارکرد یا استفاده از SQLAlchemy را تغییر نمی‌دهد. برای یادگیری عمیق نحوه‌ی کار با ORM، مستندات SQLAlchemy را در https://docs.sqlalchemy.org مطالعه کنید. مستندات ارائه‌شده در اینجا تنها به راه‌اندازی افزونه می‌پردازد، نه نحوه‌ی استفاده از SQLAlchemy.

افزونه‌ی Flask-SQLAlchemy با مدیریت خودکار ایجاد، استفاده و پاک‌سازی اشیاء SQLAlchemy که معمولاً با آن‌ها کار می‌کنید، استفاده از SQLAlchemy را ساده می‌کند. اگرچه این افزونه چند ویژگی کاربردی اضافه می‌کند، اما همچنان مانند SQLAlchemy کار می‌کند.

این صفحه شما را با استفاده‌ی پایه‌ای از Flask-SQLAlchemy آشنا می‌کند. برای دسترسی به همه‌ی قابلیت‌ها و شخصی‌سازی‌ها، باقی این مستندات از جمله مستندات API برای شیء SQLAlchemy <#flask_sqlalchemy.SQLAlchemy> را مطالعه کنید.

افزونه‌ی Flask-SQLAlchemy یک پوسته‌ساز (wrapper) پیرامون SQLAlchemy است. شما باید آموزش SQLAlchemy https://docs.sqlalchemy.org/en/20/tutorial/index.html را برای یادگیری نحوه‌ی استفاده از آن دنبال کرده و برای اطلاعات دقیق‌تر درباره‌ی قابلیت‌هایش، مستندات آن را بررسی کنید. این مستندات نحوه‌ی پیکربندی خود Flask-SQLAlchemy را نشان می‌دهند، نه نحوه‌ی کار با SQLAlchemy. از آنجا که Flask-SQLAlchemy موتور و نشست دامنه‌دار (scoped session) را به‌طور خودکار راه‌اندازی می‌کند، می‌توانید از آن بخش‌های آموزش SQLAlchemy صرف‌نظر کنید.

این راهنما فرض می‌کند که شما از SQLAlchemy 2.x استفاده می‌کنید که دارای یک API جدید برای تعریف مدل‌ها و پشتیبانی بهتر از راهنماهای نوع (type hints) و کلاس‌های داده (data classes) در پایتون است. اگر از SQLAlchemy 1.x استفاده می‌کنید، بخش شروع سریع موروثی (Legacy Quickstart) <> را ببینید.

افزونه‌ی Flask-SQLAlchemy در PyPI https://pypi.org/project/Flask-SQLAlchemy در دسترس است و می‌توان آن را با ابزارهای مختلف پایتون نصب کرد. برای نمونه، جهت نصب یا به‌روزرسانی به آخرین نسخه با استفاده از pip:

$ pip install -U Flask-SQLAlchemy

ابتدا شیء db را با استفاده از سازنده‌ی SQLAlchemy ایجاد کنید.

یک زیرکلاس از DeclarativeBase https://docs.sqlalchemy.org/en/20/orm/mapping_api.html#sqlalchemy.orm.DeclarativeBase یا DeclarativeBaseNoMeta https://docs.sqlalchemy.org/en/20/orm/mapping_api.html#sqlalchemy.orm.DeclarativeBaseNoMeta را به سازنده پاس دهید.

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):
  pass
db = SQLAlchemy(model_class=Base)

درباره‌ی سفارشی‌سازی کلاس مدل پایه، در مدل‌ها و جدول‌ها (Models and Tables) <> بیشتر بیاموزید..SS دربارهٔ شیء SQLAlchemy

پس از نمونه‌سازی، شیء db دسترسی به کلاس db.Model <#flask_sqlalchemy.SQLAlchemy.Model> جهت تعریف مدل‌ها، و db.session <#flask_sqlalchemy.SQLAlchemy.session> برای اجرای پرس‌وجوها را فراهم می‌کند.

شیء SQLAlchemy <#flask_sqlalchemy.SQLAlchemy> همچنین آرگومان‌های بیشتری را برای سفارشی‌سازی اشیایی که مدیریت می‌کند می‌پذیرد.

گام بعدی، متصل کردن افزونه به برنامهٔ Flask شما است. تنها پیکربندی لازم برای برنامهٔ Flask، کلید SQLALCHEMY_DATABASE_URI <#flask_sqlalchemy.config.SQLALCHEMY_DATABASE_URI> است. این کلید یک رشتهٔ اتصال است که به SQLAlchemy می‌گوید به چه پایگاه داده‌ای متصل شود.

شیء برنامهٔ Flask خود را ایجاد کرده، هرگونه پیکربندی را بارگذاری نمایید، و سپس با فراخوانی db.init_app <#flask_sqlalchemy.SQLAlchemy.init_app>، کلاس افزونهٔ SQLAlchemy <#flask_sqlalchemy.SQLAlchemy> را با برنامه مقداردهی اولیه کنید. این مثال به یک پایگاه دادهٔ SQLite متصل می‌شود که در پوشهٔ instance برنامه ذخیره شده است.

# create the app
app = Flask(__name__)
# configure the SQLite database, relative to the app instance folder
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///project.db"
# initialize the app with the extension
db.init_app(app)

برای توضیحات مربوط به رشته‌های اتصال و این‌که چه کلیدهای پیکربندی دیگری استفاده می‌شوند، بخش Configuration <> را ببینید.

برای تعریف یک کلاس مدل، از db.Model ارث‌بری کنید. مدل با تبدیل نام کلاس از حالت CamelCase به snake_case، نام جدول را تولید خواهد کرد.

from sqlalchemy import Integer, String
from sqlalchemy.orm import Mapped, mapped_column
class User(db.Model):
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    username: Mapped[str] = mapped_column(String, unique=True, nullable=False)
    email: Mapped[str] = mapped_column(String)

برای اطلاعات بیشتر دربارهٔ تعریف و ایجاد مدل‌ها و جدول‌ها، بخش Models and Tables <> را ببینید.

پس از اینکه تمام مدل‌ها و جدول‌ها تعریف شدند، SQLAlchemy.create_all() <#flask_sqlalchemy.SQLAlchemy.create_all> را فراخوانی کنید تا طرح‌وارهٔ جدول در پایگاه داده ایجاد شود. این کار نیازمند بافتار برنامه (application context) است. از آنجا که در این مرحله در بافتار یک درخواست نیستید، یکی را به‌صورت دستی ایجاد نمایید.

with app.app_context():
    db.create_all()

اگر مدل‌ها را در ماژول‌های دیگری تعریف کرده‌اید، باید پیش از فراخوانی create_all آن‌ها را وارد (import) کنید؛ در غیر این صورت SQLAlchemy از آن‌ها مطلع نخواهد شد.

در صورتی که جدول‌ها از پیش در پایگاه داده موجود باشند، create_all آن‌ها را به‌روزرسانی نمی‌کند. اگر ستون‌های یک مدل را تغییر دادید، از یک کتابخانهٔ مهاجرت (migration) مانند Alembic https://alembic.sqlalchemy.org همراه با Flask-Alembic https://flask-alembic.readthedocs.io یا Flask-Migrate https://flask-migrate.readthedocs.io استفاده کنید تا مهاجرت‌هایی تولید شوند که طرح‌وارهٔ پایگاه داده را به‌روزرسانی می‌کنند.

درون یک view در Flask یا یک فرمان CLI، می‌توانید از db.session برای اجرای پرس‌وجوها و تغییر داده‌های مدل استفاده نمایید.

سامانهٔ SQLAlchemy به‌طور خودکار یک متد __init__ برای هر مدل تعریف می‌کند که تمام آرگومان‌های کلیدواژه‌ای را به ستون‌های متناظر در پایگاه داده و سایر ویژگی‌ها اختصاص می‌دهد.

دستور db.session.add(obj) یک شیء را برای درج شدن به نشست (session) اضافه می‌کند. ویرایش ویژگی‌های یک شیء، آن را به‌روزرسانی می‌نماید. دستور db.session.delete(obj) یک شیء را حذف می‌کند. به یاد داشته باشید که پس از تغییر، افزودن یا حذف هرگونه داده، باید db.session.commit() را فراخوانی کنید.

دستور db.session.execute(db.select(...)) یک پرس‌وجو برای گزینش داده‌ها از پایگاه داده می‌سازد. ساخت پرس‌وجوها قابلیت اصلی SQLAlchemy است، بنابراین توصیه می‌شود آموزش آن دربارهٔ select https://docs.sqlalchemy.org/tutorial/data_select.html را مطالعه کنید تا تمام جزئیات آن را فرا بگیرید. معمولاً از متد Result.scalars() برای دریافت فهرستی از نتایج، یا از متد Result.scalar() برای دریافت یک نتیجهٔ منفرد استفاده خواهید کرد.

@app.route("/users")
def user_list():
    users = db.session.execute(db.select(User).order_by(User.username)).scalars()
    return render_template("user/list.html", users=users)
@app.route("/users/create", methods=["GET", "POST"])
def user_create():
    if request.method == "POST":
        user = User(
            username=request.form["username"],
            email=request.form["email"],
        )
        db.session.add(user)
        db.session.commit()
        return redirect(url_for("user_detail", id=user.id))
    return render_template("user/create.html")
@app.route("/user/<int:id>")
def user_detail(id):
    user = db.get_or_404(User, id)
    return render_template("user/detail.html", user=user)
@app.route("/user/<int:id>/delete", methods=["GET", "POST"])
def user_delete(id):
    user = db.get_or_404(User, id)
    if request.method == "POST":
        db.session.delete(user)
        db.session.commit()
        return redirect(url_for("user_list"))
    return render_template("user/delete.html", user=user)

ممکن است استفاده‌هایی از Model.query را برای ساخت پرس‌وجوها ببینید. این یک واسط قدیمی‌تر برای پرس‌وجوها است که در SQLAlchemy منسوخ‌شده (legacy) به شمار می‌رود. ترجیحاً به‌جای آن از db.session.execute(db.select(...)) استفاده کنید.

برای اطلاعات بیشتر دربارهٔ پرس‌وجوها، بخش Modifying and Querying Data <> را ببینید..SS نکاتی که باید به خاطر داشت

در بیشتر موارد، باید از SQLAlchemy طبق روال معمول استفاده کنید. نمونه افزونه‌ی SQLAlchemy <#flask_sqlalchemy.SQLAlchemy> موارد زیر را ایجاد و پیکربندی کرده و دسترسی به آن‌ها را فراهم می‌کند:

  • کلاس پایه مدل اعلانی SQLAlchemy.Model <#flask_sqlalchemy.SQLAlchemy.Model>. این کلاس به‌جای نیاز به __tablename__ نام جدول را به‌طور خودکار تنظیم می‌کند.
  • نشست SQLAlchemy.session <#flask_sqlalchemy.SQLAlchemy.session> که محدوده‌اش به بافتار برنامه (application context) جاری Flask محدود است. این نشست پس از هر درخواست پاک‌سازی می‌شود.
  • SQLAlchemy.metadata <#flask_sqlalchemy.SQLAlchemy.metadata> و SQLAlchemy.metadatas <#flask_sqlalchemy.SQLAlchemy.metadatas> دسترسی به هر فراداده تعریف‌شده در پیکربندی را فراهم می‌کنند.
  • SQLAlchemy.engine <#flask_sqlalchemy.SQLAlchemy.engine> و SQLAlchemy.engines <#flask_sqlalchemy.SQLAlchemy.engines> دسترسی به هر موتور تعریف‌شده در پیکربندی را فراهم می‌کنند.
  • SQLAlchemy.create_all() <#flask_sqlalchemy.SQLAlchemy.create_all> تمام جدول‌ها را ایجاد می‌کند.
  • برای اجرای پرس‌وجوها و دسترسی به نشست و موتور، باید در یک بافتار فعال برنامه Flask قرار داشته باشید.

پیکربندی هنگام فراخوانی SQLAlchemy.init_app() <#flask_sqlalchemy.SQLAlchemy.init_app> از app.config در Flask بارگذاری می‌شود. پس از آن پیکربندی مجدداً خوانده نخواهد شد. بنابراین، تمام تنظیمات پیکربندی باید پیش از راه‌اندازی اولیه برنامه انجام شوند.

شناسه یکنواخت منبع (URI) اتصال پایگاه داده که برای موتور پیش‌فرض استفاده می‌شود. این مقدار می‌تواند یک رشته یا نمونه‌ای از URL در SQLAlchemy باشد. برای مشاهده مثال‌ها به ادامه متن و Engine Configuration https://docs.sqlalchemy.org/en/20/core/engines.html مراجعه کنید.

حداقل یکی از این گزینه و SQLALCHEMY_BINDS باید تنظیم شود.

تغییر یافته در نسخه 3.0: در صورت تنظیم نشدن، دیگر به‌طور پیش‌فرض از یک پایگاه داده SQLite درون‌حافظه‌ای (in-memory) استفاده نمی‌کند.

یک دیکشنری از آرگومان‌ها برای ارسال به sqlalchemy.create_engine() https://docs.sqlalchemy.org/en/20/core/engines.html#sqlalchemy.create_engine برای موتور پیش‌فرض.

این گزینه بر آرگومان engine_options در SQLAlchemy <#flask_sqlalchemy.SQLAlchemy>، که می‌توان از آن برای تنظیم گزینه‌های پیش‌فرض تمام موتورها استفاده کرد، اولویت دارد.

تغییر یافته در نسخه 3.0: فقط به پیوند (bind) پیش‌فرض اعمال می‌شود.

اضافه‌شده در نسخه 2.4.

یک دیکشنری که کلیدهای پیوند (bind) را به گزینه‌های موتور نگاشت می‌کند. مقدار می‌تواند یک رشته یا یک نمونه URL در SQLAlchemy باشد، یا می‌تواند دیکشنری‌ای از آرگومان‌ها شامل کلید url باشد که به sqlalchemy.create_engine() https://docs.sqlalchemy.org/en/20/core/engines.html#sqlalchemy.create_engine ارسال خواهد شد. از کلید None می‌توان برای پیکربندی پیوند پیش‌فرض استفاده کرد، اما SQLALCHEMY_ENGINE_OPTIONS و SQLALCHEMY_DATABASE_URI در اولویت هستند.

حداقل یکی از این گزینه و SQLALCHEMY_DATABASE_URI باید تنظیم شود.

اضافه‌شده در نسخه 0.12.

مقدار پیش‌فرض برای echo و echo_pool برای هر موتور. این گزینه برای اشکال‌زدایی سریع اتصالات و پرس‌وجوهای صادرشده از SQLAlchemy مفید است.

تغییر یافته در نسخه 3.0: علاوه بر echo، مقدار echo_pool را نیز تنظیم می‌کند.

در صورت فعال بودن، اطلاعات مربوط به هر پرس‌وجو در طول یک درخواست ثبت خواهد شد. برای دریافت فهرستی از پرس‌وجوهای صادرشده در طول درخواست، از get_recorded_queries() <#flask_sqlalchemy.record_queries.get_recorded_queries> استفاده کنید.

تغییر یافته در نسخه 3.0: دیگر به‌طور خودکار در حالت اشکال‌زدایی (debug) یا آزمایش (testing) فعال نمی‌شود.

در صورت فعال بودن، تمام عملیات‌های insert، update و delete روی مدل‌ها ثبت شده و سپس هنگام فراخوانی session.commit()، در سیگنال‌های models_committed <#flask_sqlalchemy.track_modifications.models_committed> و before_models_committed <#flask_sqlalchemy.track_modifications.before_models_committed> ارسال می‌شوند.

این کار بار اضافی (overhead) چشمگیری به هر نشست اضافه می‌کند. ترجیحاً برای دسترسی به اطلاعات دقیقی که نیاز دارید، مستقیماً از رویدادهای SQLAlchemy's ORM Events https://docs.sqlalchemy.org/en/20/orm/events.html استفاده کنید.

تغییر یافته در نسخه 3.0: به‌طور پیش‌فرض غیرفعال است.

اضافه‌شده در نسخه 2.0.

تغییر یافته در نسخه 3.1: گزینه SQLALCHEMY_COMMIT_ON_TEARDOWN حذف شد.

تغییر یافته در نسخه 3.0: گزینه‌های SQLALCHEMY_NATIVE_UNICODE، SQLALCHEMY_POOL_SIZE، SQLALCHEMY_POOL_TIMEOUT، SQLALCHEMY_POOL_RECYCLE و SQLALCHEMY_MAX_OVERFLOW حذف شدند..SS قالب URL اتصال

برای توضیحات کامل درباره نحو (syntax)، گویش‌ها و گزینه‌ها، مستندات SQLAlchemy درباره پیکربندی موتور https://docs.sqlalchemy.org/en/20/core/engines.html را ببینید.

یک URL اتصال پایگاه داده پایه از قالب زیر استفاده می‌کند. نام کاربری، گذرواژه، میزبان و درگاه بسته به نوع پایگاه داده و پیکربندی آن اختیاری هستند.

dialect://username:password@host:port/database

در اینجا چند نمونه رشته اتصال آورده شده است:

# SQLite, relative to Flask instance path
sqlite:///project.db
# PostgreSQL
postgresql://scott:tiger@localhost/project
# MySQL / MariaDB
mysql://scott:tiger@localhost/project

پایگاه داده SQLite از کاربر یا میزبان استفاده نمی‌کند، بنابراین URLهای آن همیشه به‌جای دو اسلش با _سه_ اسلش آغاز می‌شوند. مقدار dbname یک مسیر فایل است. مسیرهای مطلق با اسلش _چهارم_ (در لینوکس یا مک) شروع می‌شوند. مسیرهای نسبی نسبت به instance_path برنامه Flask سنجیده می‌شوند https://flask.palletsprojects.com/en/stable/api/#flask.Flask.instance_path.

برخی گزینه‌های پیش‌فرض برای موتورهای SQLite و MySQL تنظیم شده‌اند تا استفاده از آن‌ها به‌طور پیش‌فرض در برنامه‌های وب کاربردی‌تر باشد.

مسیرهای نسبی فایل SQLite به‌جای دایرکتوری کاری جاری، نسبت به مسیر نمونه (instance path) برنامه Flask سنجیده می‌شوند. پایگاه‌های داده در حافظه (In-memory) از یک استخر ایستا و check_same_thread برای کارکرد در میان درخواست‌ها استفاده می‌کنند.

سرورهای MySQL (و MariaDB) طوری پیکربندی شده‌اند که اتصال‌هایی را که به مدت ۸ ساعت بدون فعالیت مانده‌اند قطع کنند، که این می‌تواند منجر به خطایی مانند 2013: Lost connection to MySQL server during query شود. یک مقدار پیش‌فرض pool_recycle برابر با ۲ ساعت (۷۲۰۰ ثانیه) استفاده می‌شود تا اتصال‌ها پیش از سررسید آن وقفه زمانی مجدداً برقرار شوند.

از آنجا که Flask-SQLAlchemy از چندین موتور پشتیبانی می‌کند، قوانینی برای اینکه کدام پیکربندی جایگزین دیگری می‌شود وجود دارد. بیشتر برنامه‌ها تنها یک پایگاه داده خواهند داشت و فقط نیاز به استفاده از SQLALCHEMY_DATABASE_URI و SQLALCHEMY_ENGINE_OPTIONS دارند.

  • اگر آرگومان engine_options به SQLAlchemy <#flask_sqlalchemy.SQLAlchemy> داده شود، گزینه‌های پیش‌فرض را برای همه موتورها تنظیم می‌کند. SQLALCHEMY_ECHO مقدار پیش‌فرض را برای هر دو گزینه echo و echo_pool برای تمام موتورها تعیین می‌کند.
  • گزینه‌های مربوط به هر موتور در SQLALCHEMY_BINDS بر این مقادیر پیش‌فرض اولویت دارند.
  • SQLALCHEMY_ENGINE_OPTIONS بر کلید None در SQLALCHEMY_BINDS اولویت دارد، و SQLALCHEMY_DATABASE_URI بر کلید url در گزینه‌های آن موتور اولویت می‌یابد.

برخی از پایگاه‌های داده ممکن است طوری پیکربندی شده باشند که اتصالات غیرفعال را پس از گذشت مدتی ببندند. MySQL و MariaDB به‌طور پیش‌فرض برای این منظور پیکربندی شده‌اند، اما سرویس‌های پایگاه داده نیز ممکن است چنین محدودیتی را پیکربندی کنند. این موضوع می‌تواند به خطایی مانند 2013: Lost connection to MySQL server during query منجر شود.

اگر با این خطا مواجه شدید، مقدار pool_recycle را در گزینه‌های موتور به مقداری کمتر از وقفه زمانی پایگاه داده تنظیم کنید.

همچنین، اگر انتظار دارید پایگاه داده مکرراً اتصالات را ببندد، مانند زمانی که درون یک کانتینر در حال اجراست که ممکن است بازراه‌اندازی شود، می‌توانید pool_pre_ping را تنظیم کنید.

برای اطلاعات بیشتر، مستندات SQLAlchemy درباره مدیریت قطع اتصال https://docs.sqlalchemy.org/core/pooling.html#dealing-with-disconnects را ببینید..SS مدل‌ها و جدول‌ها (Models and Tables)

برای تعریف مدل‌ها از کلاس db.Model یا برای ایجاد جدول‌ها از کلاس db.Table استفاده کنید. هر دو مورد کلیدهای مقیدسازی (bind keys) در Flask-SQLAlchemy را برای انتساب به یک موتور (engine) مشخص مدیریت می‌کنند.

SQLAlchemy نسخهٔ 2.x چند کلاس پایهٔ ممکن را برای مدل‌های شما ارائه می‌دهد: DeclarativeBase https://docs.sqlalchemy.org/en/20/orm/mapping_api.html#sqlalchemy.orm.DeclarativeBase یا DeclarativeBaseNoMeta https://docs.sqlalchemy.org/en/20/orm/mapping_api.html#sqlalchemy.orm.DeclarativeBaseNoMeta.

یک زیرکلاس از یکی از این کلاس‌ها ایجاد کنید:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy.orm import DeclarativeBase
class Base(DeclarativeBase):
  pass

در صورت تمایل، می‌توانید پشتیبانی درونی SQLAlchemy از کلاس‌های داده (data classes) https://docs.sqlalchemy.org/en/20/changelog/whatsnew_20.html#native-support-for-dataclasses-mapped-as-orm-models را با افزودن MappedAsDataclass به عنوان یک کلاس والد دیگر فعال کنید.

from sqlalchemy.orm import DeclarativeBase, MappedAsDataclass
class Base(DeclarativeBase, MappedAsDataclass):
  pass

به صورت اختیاری می‌توانید شیء SQLAlchemy <#flask_sqlalchemy.SQLAlchemy> را با یک شیء سفارشی MetaData https://docs.sqlalchemy.org/en/20/core/metadata.html#sqlalchemy.schema.MetaData بسازید. این کار به شما امکان می‌دهد یک قرارداد نام‌گذاری قیدها (constraint naming convention) سفارشی https://docs.sqlalchemy.org/core/constraints.html#constraint-naming-conventions مشخص کنید. این قابلیت نام‌های قیدها را یکدست و قابل پیش‌بینی می‌کند که هنگام استفاده از مهاجرت‌ها (migrations) طبق توضیحات Alembic https://alembic.sqlalchemy.org/en/latest/naming.html بسیار سودمند است.

from sqlalchemy import MetaData
class Base(DeclarativeBase):
    metadata = MetaData(naming_convention={
        "ix": 'ix_%(column_0_label)s',
        "uq": "uq_%(table_name)s_%(column_0_name)s",
        "ck": "ck_%(table_name)s_%(constraint_name)s",
        "fk": "fk_%(table_name)s_%(column_0_name)s_%(referred_table_name)s",
        "pk": "pk_%(table_name)s"
    })

پس از تعریف کلاس پایه، شیء db را با استفاده از سازندهٔ SQLAlchemy ایجاد کنید.

db = SQLAlchemy(model_class=Base)

برای دریافت اطلاعات کامل پیرامون تعریف اعلانی (declarative) کلاس‌های مدل، به مستندات اعلانی SQLAlchemy https://docs.sqlalchemy.org/en/20/orm/declarative_tables.html مراجعه کنید.

برای ساخت یک کلاس مدل، از db.Model ارث‌بری کنید. بر خلاف SQLAlchemy خام، اگر __tablename__ تنظیم نشده باشد و ستون کلید اصلی تعریف شده باشد، مدل Flask-SQLAlchemy به طور خودکار نام جدول را تولید می‌کند.

from sqlalchemy.orm import Mapped, mapped_column
class User(db.Model):
    id: Mapped[int] = mapped_column(db.Integer, primary_key=True)
    username: Mapped[str] = mapped_column(db.String, unique=True, nullable=False)
    email: Mapped[str] = mapped_column(db.String)

تعریف یک مدل، آن را در پایگاه داده ایجاد نمی‌کند. پس از تعریف آن‌ها، از create_all() <#flask_sqlalchemy.SQLAlchemy.create_all> برای ایجاد مدل‌ها و جدول‌ها استفاده کنید. اگر مدل‌ها را در زیرماژول‌ها تعریف کرده‌اید، باید پیش از فراخوانی create_all آن‌ها را وارد (import) کنید تا SQLAlchemy از آن‌ها آگاه باشد.

with app.app_context():
    db.create_all()

برای اطلاعات کامل درباره تعریف اشیاء جدول، به مستندات جدول SQLAlchemy در https://docs.sqlalchemy.org/en/20/core/metadata.html مراجعه کنید.

برای تعریف جدول‌ها، نمونه‌هایی از db.Table ایجاد کنید. این کلاس نام جدول و سپس هر ستون و سایر اجزای جدول مانند ستون‌ها و محدودیت‌ها را می‌پذیرد. برخلاف SQLAlchemy خام، آرگومان metadata الزامی نیست. یک metadata بر اساس آرگومان bind_key انتخاب خواهد شد، یا از مقدار پیش‌فرض استفاده می‌شود.

یک دلیل رایج برای ایجاد مستقیم جدول، هنگام تعریف روابط چند‌به‌چند (many-to-many) است. جدول رابط (association table) نیازی به کلاس مدل اختصاصی خود ندارد، چرا که از طریق ویژگی‌های رابطه مرتبط در مدل‌های مربوطه در دسترس خواهد بود.

import sqlalchemy as sa
user_book_m2m = db.Table(
    "user_book",
    sa.Column("user_id", sa.ForeignKey(User.id), primary_key=True),
    sa.Column("book_id", sa.ForeignKey(Book.id), primary_key=True),
)

اگر به پایگاه‌داده‌ای متصل می‌شوید که از قبل دارای جدول است، SQLAlchemy می‌تواند آن طرح‌واره (schema) را شناسایی کرده و جدول‌ها را به همراه ستون‌هایشان به‌طور خودکار بسازد. به این عمل بازتاب (reflection) گفته می‌شود. این جدول‌ها همچنین می‌توانند به جای تعریف مدل کامل، با استفاده از ویژگی __table__ به کلاس‌های مدل تخصیص داده شوند.

متد reflect() <#flask_sqlalchemy.SQLAlchemy.reflect> را روی افزونه فراخوانی کنید. این متد تمام جدول‌ها را برای هر bind key بازتاب می‌دهد. ویژگی tables مربوط به هر metadata شامل اشیاء جدول شناسایی‌شده خواهد بود.

with app.app_context():
    db.reflect()
class User:
    __table__ = db.metadatas["auth"].tables["user"]

در بیشتر موارد، تعریف کلاس‌های مدل توسط خودتان نگه‌داری‌پذیرتر خواهد بود. شما تنها نیاز دارید مدل‌ها و ستون‌هایی را که واقعاً استفاده می‌کنید تعریف نمایید، حتی اگر به یک طرح‌واره گسترده‌تر متصل شوید. محیط‌های توسعه یکپارچه (IDEها) ویژگی‌های موجود را شناسایی می‌کنند و ابزارهای مهاجرت مانند Alembic می‌توانند تغییرات را تشخیص داده و مهاجرت‌های طرح‌واره را تولید کنند.

برای کسب اطلاعات بیشتر پیرامون اصلاح داده‌ها با ORM، به آموزش ORM در SQLAlchemy در https://docs.sqlalchemy.org/tutorial/orm_data_manipulation.html و سایر مستندات SQLAlchemy مراجعه کنید.

برای درج داده، شیء مدل را به db.session.add() ارسال کنید:

user = User()
db.session.add(user)
db.session.commit()

برای به‌روزرسانی داده، ویژگی‌های روی اشیاء مدل را تغییر دهید:

user.verified = True
db.session.commit()

برای حذف داده، شیء مدل را به db.session.delete() ارسال کنید:

db.session.delete(user)
db.session.commit()

پس از اصلاح داده‌ها، باید db.session.commit() را فراخوانی کنید تا تغییرات در پایگاه‌داده اعمال (commit) شوند. در غیر این صورت، در پایان درخواست نادیده گرفته شده و دور ریخته خواهند شد..SS Select

برای اطلاعات بیشتر در مورد پرس‌وجوی داده‌ها با استفاده از ORM، به راهنمای پرس‌وجوی SQLAlchemy https://docs.sqlalchemy.org/orm/queryguide.html و سایر مستندات SQLAlchemy مراجعه کنید.

پرس‌وجوها از طریق db.session.execute() اجرا می‌شوند. آن‌ها را می‌توان با استفاده از select() https://docs.sqlalchemy.org/en/20/core/selectable.html#sqlalchemy.sql.expression.select ساخت. اجرای یک select شیء Result https://docs.sqlalchemy.org/en/20/core/connections.html#sqlalchemy.engine.Result را بازمی‌گرداند که متدهای متعددی برای کار با ردیف‌های بازگردانده‌شده دارد.

user = db.session.execute(db.select(User).filter_by(username=username)).scalar_one()
users = db.session.execute(db.select(User).order_by(User.username)).scalars()

اگر یک تابع view در Flask می‌نویسید، اغلب مفید است که برای ورودی‌های ناموجود، خطای 404 Not Found بازگردانید. Flask-SQLAlchemy چند متد پرس‌وجوی اضافی در اختیارتان می‌گذارد.

  • متد SQLAlchemy.get_or_404() <#flask_sqlalchemy.SQLAlchemy.get_or_404> در صورتی که ردیف با شناسه داده‌شده وجود نداشته باشد یک خطای 404 ایجاد می‌کند، در غیر این صورت نمونه مورد نظر را بازمی‌گرداند.
  • متد SQLAlchemy.first_or_404() <#flask_sqlalchemy.SQLAlchemy.first_or_404> در صورتی که پرس‌وجو هیچ نتیجه‌ای بازنگرداند یک خطای 404 ایجاد می‌کند، در غیر این صورت اولین نتیجه را بازمی‌گرداند.
  • متد SQLAlchemy.one_or_404() <#flask_sqlalchemy.SQLAlchemy.one_or_404> در صورتی که پرس‌وجو دقیقاً یک نتیجه بازنگرداند یک خطای 404 ایجاد می‌کند، در غیر این صورت نتیجه را بازمی‌گرداند.
@app.route("/user-by-id/<int:id>")
def user_by_id(id):
    user = db.get_or_404(User, id)
    return render_template("show_user.html", user=user)
@app.route("/user-by-username/<username>")
def user_by_username(username):
    user = db.one_or_404(db.select(User).filter_by(username=username))
    return render_template("show_user.html", user=user)

می‌توانید یک پیام سفارشی به خطای 404 اضافه کنید:

user = db.one_or_404(
    db.select(User).filter_by(username=username),
    description=f"No user named '{username}'."
)

ممکن است استفاده از Model.query یا session.query را برای ساخت پرس‌وجوها مشاهده کنید. این رابط پرس‌وجو در SQLAlchemy قدیمی (legacy) محسوب می‌شود. ترجیحاً به جای آن از session.execute(select(...)) استفاده کنید.

برای دیدن مستندات به Legacy Query Interface <> مراجعه کنید.

اگر نتایج زیادی دارید، ممکن است بخواهید در هر نوبت فقط تعداد مشخصی را نمایش دهید، تا به کاربر اجازه دهید با کلیک روی پیوندهای بعدی و قبلی صفحات داده را ببیند. به این عمل گاهی pagination (صفحه‌بندی) گفته می‌شود و از فعل paginate استفاده می‌کند.

متد SQLAlchemy.paginate() <#flask_sqlalchemy.SQLAlchemy.paginate> را روی یک عبارت select فراخوانی کنید تا یک شیء Pagination <#flask_sqlalchemy.pagination.Pagination> دریافت کنید.

در طول یک درخواست، این متد آرگومان‌های page و per_page را از رشته پرس‌وجوی request.args دریافت می‌کند. برای جلوگیری از درخواست بیش از حد نتایج در یک صفحه واحد توسط کاربران، مقدار max_per_page را ارسال کنید. در صورت عدم تعیین، مقادیر پیش‌فرض صفحه ۱ با ۲۰ آیتم در هر صفحه خواهد بود.

page = db.paginate(db.select(User).order_by(User.join_date))
return render_template("user/list.html", page=page)

صفت Pagination.items <#flask_sqlalchemy.pagination.Pagination.items> شیء Pagination <#flask_sqlalchemy.pagination.Pagination>، فهرست آیتم‌های صفحه جاری است. همچنین می‌توان مستقیماً روی خود شیء پیمایش کرد.

<ul>
  {% for user in page %}
    <li>{{ user.username }}
  {% endfor %}
</ul>

شیء Pagination <#flask_sqlalchemy.pagination.Pagination> صفت‌هایی دارد که می‌توان با پیمایش روی شماره صفحات و بررسی صفحه جاری، از آن‌ها برای ایجاد یک ویجت انتخاب صفحه استفاده کرد. متد iter_pages() <#flask_sqlalchemy.pagination.Pagination.iter_pages> حداکثر سه گروه از اعداد را که با None جدا شده‌اند تولید می‌کند. حالت پیش‌فرض آن نمایش ۲ شماره صفحه در هر دو انتها، ۲ شماره پیش از صفحه جاری، خود صفحه جاری، و ۴ شماره پس از صفحه جاری است. برای نمونه، اگر ۲۰ صفحه وجود داشته باشد و صفحه جاری ۷ باشد، مقادیر زیر حاصل می‌شوند.

users.iter_pages()
[1, 2, None, 5, 6, 7, 8, 9, 10, 11, None, 19, 20]

می‌توانید از صفت total <#flask_sqlalchemy.pagination.Pagination.total> برای نمایش تعداد کل نتایج، و از first <#flask_sqlalchemy.pagination.Pagination.first> و last <#flask_sqlalchemy.pagination.Pagination.last> برای نمایش محدوده آیتم‌های صفحه جاری استفاده کنید.

ماکروی Jinja زیر یک ویجت صفحه‌بندی ساده را ارائه می‌دهد.

{% macro render_pagination(pagination, endpoint) %}
  <div class=page-items>
    {{ pagination.first }} - {{ pagination.last }} of {{ pagination.total }}
  </div>
  <div class=pagination>
    {% for page in pagination.iter_pages() %}
      {% if page %}
        {% if page != pagination.page %}
          <a href="{{ url_for(endpoint, page=page) }}">{{ page }}</a>
        {% else %}
          <strong>{{ page }}</strong>
        {% endif %}
      {% else %}
        <span class=ellipsis>…</span>
      {% endif %}
    {% endfor %}
  </div>
{% endmacro %}

برای اجرای پرس‌وجوها و دسترسی به db.engine و db.session به یک کانتکست فعال برنامه Flask نیاز است. دلیل این امر آن است که محدوده نشست به کانتکست محدود شده است تا پس از هر درخواست یا دستور CLI به‌درستی پاک‌سازی شود.

صرف‌نظر از نحوه مقداردهی اولیه برنامه با این افزونه، برنامه برای استفاده‌های بعدی ذخیره نمی‌شود. در عوض، این افزونه از پروکسی current_app فلاسک برای دریافت برنامه فعال استفاده می‌کند، که این امر نیازمند یک کانتکست برنامه فعال است.

هنگامی که Flask در حال مدیریت یک درخواست یا یک دستور CLI است، کانتکست برنامه به‌طور خودکار اعمال (push) می‌شود. بنابراین برای استفاده از پایگاه‌داده هنگام درخواست‌ها یا دستورهای CLI نیازی به انجام کار خاصی ندارید.

اگر در زمانی که کانتکست برنامه فعال نیست سعی در استفاده از پایگاه‌داده داشته باشید، با خطای زیر مواجه خواهید شد.

RuntimeError: Working outside of application context.
This typically means that you attempted to use functionality that needed
the current application. To solve this, set up an application context
with app.app_context(). See the documentation for more information.

اگر در موقعیتی قرار گرفتید که به پایگاه‌داده نیاز دارید اما کانتکست فعالی وجود ندارد، می‌توانید با استفاده از app_context یکی را فعال (push) کنید. برای نمونه، این کار هنگام فراخوانی db.create_all جهت ساخت جدول‌ها متداول است.

def create_app():
    app = Flask(__name__)
    app.config.from_object("project.config")
    import project.models
    with app.app_context():
        db.create_all()
    return app

اگر برنامهٔ خود را با استفاده از کلاینت آزمایشی Flask جهت ارسال درخواست به endpointهای خود می‌آزمایید، کانتکست به عنوان بخشی از درخواست در دسترس خواهد بود. اگر نیاز دارید موردی را مستقیماً روی پایگاه داده یا مدل‌های خود بیازمایید، به‌جای اقدام از طریق یک درخواست، باید کانتکست را به‌صورت دستی اعمال (push) کنید.

کانتکست را دقیقاً در همان‌جایی و به همان میزانی که برای هر آزمون مورد نیاز است push کنید. کانتکست برنامه (application context) را به‌صورت سراسری برای تمام آزمون‌ها پوش نکنید، چرا که می‌تواند در روند پاک‌سازی session تداخل ایجاد کند.

def test_user_model(app):
    user = User()
    with app.app_context():
        db.session.add(user)
        db.session.commit()

اگر متوجه شدید که آزمون‌های بسیاری را به این شکل می‌نویسید، می‌توانید از یک fixture در pytest برای پوش کردن کانتکست جهت یک آزمون مشخص استفاده کنید.

import pytest
@pytest.fixture
def app_ctx(app):
    with app.app_context():
        yield
@pytest.mark.usefixtures("app_ctx")
def test_user_model():
    user = User()
    db.session.add(user)
    db.session.commit()

SQLAlchemy می‌تواند به‌طور هم‌زمان به بیش از یک پایگاه داده متصل شود. این ابزار به موتورهای مختلف با عنوان "binds" (پیوندها) اشاره می‌کند. Flask-SQLAlchemy سازوکار پیوندها را با مرتبط ساختن هر موتور با یک رشتهٔ کوتاه تحت عنوان یک "bind key"، و سپس پیوند دادن هر مدل و جدول با یک bind key ساده‌سازی می‌کند. نشست (session) بر اساس bind key مربوط به موردی که مورد پرس‌وجو قرار می‌گیرد، موتور مورد استفاده را انتخاب خواهد کرد. اگر هیچ bind key تعیین نشده باشد، از موتور پیش‌فرض استفاده می‌شود.

پیوند پیش‌فرض همچنان با مقداردهی SQLALCHEMY_DATABASE_URI <#flask_sqlalchemy.config.SQLALCHEMY_DATABASE_URI> و SQLALCHEMY_ENGINE_OPTIONS <#flask_sqlalchemy.config.SQLALCHEMY_ENGINE_OPTIONS> برای هرگونه گزینه‌های موتور پیکربندی می‌شود. پیوندهای اضافی در SQLALCHEMY_BINDS <#flask_sqlalchemy.config.SQLALCHEMY_BINDS> تعیین می‌شوند که یک دیکشنری نگاشت‌کنندهٔ bind keyها به URLهای موتور است. برای تعیین گزینه‌های موتور برای یک پیوند، مقدار می‌تواند به‌جای تنها یک رشتهٔ URL، دیکشنری‌ای از گزینه‌های موتور همراه با کلید "url" باشد.

SQLALCHEMY_DATABASE_URI = "postgresql:///main"
SQLALCHEMY_BINDS = {
    "meta": "sqlite:////path/to/meta.db",
    "auth": {
        "url": "mysql://localhost/users",
        "pool_recycle": 3600,
    },
}

Flask-SQLAlchemy برای هر پیوندِ پیکربندی‌شده، یک metadata و موتور ایجاد خواهد کرد. مدل‌ها و جدول‌های دارای یک bind key در metadata مربوطه ثبت می‌شوند، و session با استفاده از موتور متناظر روی آن‌ها پرس‌وجو انجام می‌دهد.

برای تنظیم پیوند برای یک مدل، صفت کلاسی __bind_key__ را تنظیم کنید. تعیین نکردن bind key معادل تنظیم آن روی None، یعنی کلید پیش‌فرض است.

class User(db.Model):
    __bind_key__ = "auth"
    id = db.Column(db.Integer, primary_key=True)

مدل‌هایی که از این مدل ارث‌بری می‌کنند، همان bind key را به اشتراک خواهند گذاشت، یا می‌توانند آن را بازنویسی (override) کنند.

برای تنظیم پیوند برای یک جدول، آرگومان کلیدواژه‌ای bind_key را پاس دهید.

user_table = db.Table(
    "user",
    db.Column("id", db.Integer, primary_key=True),
    bind_key="auth",
)

در نهایت، session مقدار bind key را در metadata مرتبط با مدل یا جدول جستجو می‌کند. این وابستگی در زمان ایجاد شکل می‌گیرد؛ بنابراین، تغییر bind key پس از ایجاد یک مدل یا جدول هیچ تأثیری نخواهد داشت..SS دسترسی به فراداده و موتورها (Accessing Metadata and Engines)

ممکن است نیاز به بررسی فراداده یا موتور برای یک bind داشته باشید. توجه داشته باشید که باید پرس‌وجوها را از طریق session اجرا کنید، نه مستقیماً روی engine.

موتور پیش‌فرض SQLAlchemy.engine <#flask_sqlalchemy.SQLAlchemy.engine> و فراداده پیش‌فرض SQLAlchemy.metadata <#flask_sqlalchemy.SQLAlchemy.metadata> است. SQLAlchemy.engines <#flask_sqlalchemy.SQLAlchemy.engines> و SQLAlchemy.metadatas <#flask_sqlalchemy.SQLAlchemy.metadatas> دیکشنری‌هایی هستند که تمام کلیدهای bind را نگاشت می‌کنند.

متدهای create_all() <#flask_sqlalchemy.SQLAlchemy.create_all> و drop_all() <#flask_sqlalchemy.SQLAlchemy.drop_all> به‌طور پیش‌فرض بر روی تمام bindها عمل می‌کنند. آرگومان bind_key در این متدها می‌تواند یک رشته یا None برای عمل روی یک bind تکی، یا فهرستی از رشته‌ها یا None برای عمل بر روی زیرمجموعه‌ای از bindها باشد. از آنجا که این متدها به engineها دسترسی دارند، باید درون یک application context فراخوانی شوند.

# create tables for all binds
db.create_all()
# create tables for the default and "auth" binds
db.create_all(bind_key=[None, "auth"])
# create tables for the "meta" bind
db.create_all(bind_key="meta")
# drop tables for the default bind
db.drop_all(bind_key=None)

هشدار:

این ویژگی صرفاً برای اشکال‌زدایی در نظر گرفته شده است.

ابزار Flask-SQLAlchemy می‌تواند برخی اطلاعات را درباره هر پرس‌وجویی که در طول یک درخواست اجرا می‌شود ثبت کند. این اطلاعات را می‌توان سپس برای کمک به اشکال‌زدایی کارایی بازیابی کرد. برای مثال، می‌تواند نشان دهد که یک رابطه تعداد زیادی دستور select مجزا اجرا کرده است، یا پرس‌وجویی را که اجرای آن زمان زیادی برده آشکار سازد.

برای فعال‌سازی این ویژگی، SQLALCHEMY_RECORD_QUERIES <#flask_sqlalchemy.config.SQLALCHEMY_RECORD_QUERIES> را در پیکربندی برنامه Flask روی True تنظیم کنید. از get_recorded_queries() <#flask_sqlalchemy.record_queries.get_recorded_queries> برای دریافت فهرستی از اشیاء حاوی اطلاعات پرس‌وجو استفاده کنید. هر شیء دارای مشخصه‌های زیر است:

رشته SQL تولیدشده توسط SQLAlchemy همراه با جایگزین‌های پارامتر.
پارامترهای ارسال‌شده همراه با عبارت SQL.
اطلاعات زمان‌بندی درباره زمان آغاز اجرای پرس‌وجو و زمان بازگشت نتایج. دقت و مقدار آن به سیستم‌عامل بستگی دارد.
مدت‌زمانی که اجرای پرس‌وجو به ثانیه طول کشیده است.
توضیحی متنی درباره اینکه پرس‌وجو در کجای کد برنامه اجرا شده است. این مقدار ممکن است در برخی موارد نامشخص باشد.

هشدار:

ردیابی تغییرات، سربار پردازشی قابل توجهی به همراه دارد. در بیشتر موارد، استفاده مستقیم از رویدادهای SQLAlchemy https://docs.sqlalchemy.org/core/event.html نتیجه بهتری به همراه خواهد داشت.

ابزار Flask-SQLAlchemy می‌تواند session خود را طوری تنظیم کند که درج‌ها، به‌روزرسانی‌ها و حذف‌های مدل‌ها را ردیابی کرده و سپس یک سیگنال Blinker را به همراه فهرستی از این تغییرات، پیش از فراخوانی‌های session.flush() و session.commit() یا در حین آن‌ها ارسال نماید.

برای فعال‌سازی این ویژگی، SQLALCHEMY_TRACK_MODIFICATIONS <#flask_sqlalchemy.config.SQLALCHEMY_TRACK_MODIFICATIONS> را در پیکربندی برنامه Flask تنظیم کنید. سپس یک شنونده به models_committed <#flask_sqlalchemy.track_modifications.models_committed> (که پس از commit منتشر می‌شود) یا before_models_committed <#flask_sqlalchemy.track_modifications.before_models_committed> (که پیش از commit منتشر می‌شود) اضافه کنید.

from flask_sqlalchemy.track_modifications import models_committed
def get_modifications(sender: Flask, changes: list[tuple[t.Any, str]]) -> None:
    ...
models_committed.connect(get_modifications)

اشیای مختلفی که توسط افزونه مدیریت می‌شوند را می‌توان با ارسال آرگومان‌ها به سازندهٔ SQLAlchemy <#flask_sqlalchemy.SQLAlchemy> سفارشی‌سازی کرد.

تمام مدل‌های SQLAlchemy از یک کلاس پایهٔ اعلانی ارث‌بری می‌کنند. این کلاس در Flask-SQLAlchemy به‌صورت db.Model ارائه می‌شود که همهٔ مدل‌ها آن را گسترش می‌دهند. این رفتار را می‌توان با ایجاد زیرکلاس از حالت پیش‌فرض و ارسال کلاس سفارشی به model_class سفارشی‌سازی کرد.

مثال زیر به هر مدل یک کلید اصلی عدد صحیح، یا یک کلید خارجی برای وراثت جدول پیوسته (joined-table inheritance) اختصاص می‌دهد.

نکته:

استفاده از کلید اصلی عدد صحیح برای همه چیز لزوماً بهترین طراحی پایگاه داده نیست (این موضوع به نیازمندی‌های پروژهٔ شما بستگی دارد)، این تنها یک مثال است.
from sqlalchemy import Integer, String, ForeignKey
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, declared_attr
class Base(DeclarativeBase):
    @declared_attr.cascading
    @classmethod
    def id(cls):
        for base in cls.__mro__[1:-1]:
            if getattr(base, "__table__", None) is not None:
                    return mapped_column(ForeignKey(base.id), primary_key=True)
            else:
                return mapped_column(Integer, primary_key=True)
db = SQLAlchemy(app, model_class=Base)
class User(db.Model):
    name: Mapped[str] = mapped_column(String)
class Employee(User):
    title: Mapped[str] = mapped_column(String)

اگر رفتاری تنها برای برخی مدل‌ها مورد نیاز است و نه همهٔ آن‌ها، از یک کلاس پایهٔ مدل انتزاعی برای سفارشی‌سازی همان مدل‌ها استفاده کنید. برای مثال، اگر لازم باشد برخی مدل‌ها زمان ایجاد یا به‌روزرسانی شدن خود را پیگیری کنند.

from datetime import datetime
from sqlalchemy import DateTime, Integer, String
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, declared_attr
class TimestampModel(db.Model):
    __abstract__ = True
    created: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=datetime.utcnow)
    updated: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
class Author(db.Model):
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    username: Mapped[str] = mapped_column(String, unique=True, nullable=False)
class Post(TimestampModel):
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    title: Mapped[str] = mapped_column(String, nullable=False)

این کار را می‌توان با یک کلاس میکسین (mixin) و ارث‌بری جداگانه از db.Model نیز انجام داد.

class TimestampMixin:
    created: Mapped[datetime] = mapped_column(DateTime, nullable=False, default=datetime.utcnow)
    updated: Mapped[datetime] = mapped_column(DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
class Post(TimestampMixin, db.Model):
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    title: Mapped[str] = mapped_column(String, nullable=False)

برخی پروژه‌ها ترجیح می‌دهند مقدار __tablename__ هر مدل را به صورت دستی تعیین کنند و به تشخیص و تولید خودکار Flask-SQLAlchemy متکی نباشند. روش ساده برای این کار، تنظیم __tablename__ برای هر مدل و دست نزدن به کلاس پایه است. با این حال، تولید نام جدول را می‌توان با تنظیم disable_autonaming=True در سازنده SQLAlchemy غیرفعال کرد.

class Base(sa_orm.DeclarativeBase):
    pass
db = SQLAlchemy(app, model_class=Base, disable_autonaming=True)

کلاس Session <#flask_sqlalchemy.session.Session> در Flask-SQLAlchemy بر اساس کلید bind مرتبط با مدل یا جدول، موتور مناسب را برای اجرای پرس‌وجو انتخاب می‌کند. با این حال، استراتژی‌های دیگری مانند شاردینگ افقی (horizontal sharding) وجود دارند که می‌توان آن‌ها را با یک کلاس session متفاوت پیاده‌سازی کرد. از کلید class_ در آرگومان session_options افزونه برای تغییر کلاس session استفاده می‌شود.

Flask-SQLAlchemy همواره نمونه افزونه را به عنوان آرگومان db به session ارسال می‌کند، بنابراین این کلاس برای ادامه کار باید آن را بپذیرد. از این موضوع می‌توان برای دسترسی به db.engines استفاده کرد.

from sqlalchemy.ext.horizontal_shard import ShardedSession
from flask_sqlalchemy.session import Session
class CustomSession(ShardedSession, Session):
    ...
db = SQLAlchemy(session_options={"class_": CustomSession})

هشدار:

رابط query در SQLAlchemy قدیمی (legacy) محسوب می‌شود. این شامل session.query، Model.query، db.Query و رابطه‌های lazy="dynamic" است. ترجیحاً به جای آن از session.execute(select(...)) استفاده کنید.

سفارشی‌سازی رابط پرس‌وجوی (query) مورد استفاده توسط session، مدل‌ها و رابطه‌ها امکان‌پذیر است. این قابلیت می‌تواند برای افزودن متدهای query بیشتر به کار رود. برای مثال، می‌توانید متد get_or را اضافه کنید که یک سطر را دریافت کرده یا یک مقدار پیش‌فرض را برمی‌گرداند.

from flask_sqlalchemy.query import Query
class GetOrQuery(Query):
    def get_or(self, ident, default=None):
        out = self.get(ident)
        if out is None:
            return default
        return out
db = SQLAlchemy(query_class=GetOrQuery)
user = User.query.get_or(user_id, anonymous_user)

ارسال آرگومان query_class موجب سفارشی‌سازی db.Query، db.session.query، Model.query و رابطه‌های db.relationship(lazy="dynamic") می‌شود. همچنین سفارشی‌سازی این موارد به ازای هر شیء به صورت جداگانه امکان‌پذیر است.

برای سفارشی‌سازی ویژگی query یک مدل خاص، مشخصه query_class را روی کلاس مدل تنظیم کنید.

class User(db.Model):
    query_class = GetOrQuery

برای سفارشی‌سازی یک رابطه پویای (dynamic) خاص، آرگومان query_class را به رابطه ارسال کنید.

db.relationship(User, lazy="dynamic", query_class=GetOrQuery)

برای سفارشی‌سازی صرفاً session.query، کلید query_cls را به آرگومان session_options در سازنده ارسال کنید.

db = SQLAlchemy(session_options={"query_cls": GetOrQuery})

ابزار SQLAlchemy را با Flask یکپارچه‌سازی می‌کند. این کلاس برپایی یک یا چند موتور (engine)، ارتباط جدول‌ها و مدل‌ها با موتورهای مشخص، و پاک‌سازی اتصال‌ها و نشست‌ها (sessions) را پس از هر درخواست مدیریت می‌کند.

تنها پیکربندی موتور به هر برنامه اختصاص دارد؛ سایر موارد مانند مدل، جدول، متادیتا و نشست بین تمام برنامه‌هایی که از آن نمونهٔ افزونه استفاده می‌کنند به اشتراک گذاشته می‌شود. متد init_app() را برای پیکربندی افزونه روی یک برنامه فراخوانی کنید.

پس از ایجاد افزونه، کلاس‌های مدل را با زیرکلاس‌سازی از Model و کلاس‌های جدول را با Table بسازید. این موارد پیش از فراخوانی init_app() نیز قابل دسترسی هستند، که تعریف مدل‌ها را به‌صورت جداگانه از برنامه ممکن می‌سازد.

دسترسی به session و engine نیازمند یک بافت برنامه (application context) فعال Flask است. این شامل متدهایی مانند create_all() نیز می‌شود که از موتور استفاده می‌کنند.

این کلاس همچنین امکان دسترسی به شناسه‌های موجود در ماژول‌های sqlalchemy و sqlalchemy.orm متعلق به SQLAlchemy را فراهم می‌کند. برای نمونه، می‌توانید به جای وارد کردن sqlalchemy.Column و sqlalchemy.orm.relationship، از db.Column و db.relationship استفاده کنید. این قابلیت هنگام تعریف مدل‌ها بسیار مناسب و راحت است.

پارامترها (Parameters)

تغییریافته در نسخهٔ 3.1.0: پارامتر metadata همچنان می‌تواند با کلاس‌های SQLAlchemy 1.x استفاده شود، اما هنگام استفاده از سبک اعلانی کلاس‌های SQLAlchemy 2.x نادیده گرفته می‌شود. به جای آن، متادیتا را روی کلاس Base خود مشخص کنید.

تغییریافته در نسخهٔ 3.1.0: پارامتر disable_autonaming اضافه شد.

تغییریافته در نسخهٔ 3.1.0: پارامتر model_class تغییر یافت تا زیرکلاس declarative base از SQLAlchemy 2.x را بپذیرد.

تغییریافته در نسخهٔ 3.0: برای دسترسی به session و engine همیشه یک بافت برنامهٔ فعال Flask الزامی است.

تغییریافته در نسخهٔ 3.0: برای هر bind key از metadata جداگانه‌ای استفاده می‌شود.

تغییریافته در نسخهٔ 3.0: پارامتر engine_options به عنوان پیش‌فرض پیش از پیکربندی هر موتور اعمال می‌شود.

تغییریافته در نسخهٔ 3.0: کلاس نشست را می‌توان در session_options سفارشی‌سازی کرد.

تغییریافته در نسخهٔ 3.0: پارامتر add_models_to_shell اضافه شد.

تغییریافته در نسخهٔ 3.0: موتورها هنگام فراخوانی init_app ایجاد می‌شوند، نه در نخستین باری که به آن‌ها دسترسی پیدا می‌شود.

تغییریافته در نسخهٔ 3.0: تمام پارامترها به جز app فقط به‌صورت کلیدواژه‌ای (keyword-only) هستند.

تغییریافته در نسخهٔ 3.0: نمونهٔ افزونه مستقیماً به عنوان app.extensions["sqlalchemy"] ذخیره می‌شود.

تغییریافته در نسخهٔ 3.0: متدهای راه‌اندازی با زیرخط آغازین تغییر نام یافتند. این‌ها رابط‌های داخلی تلقی می‌شوند و ممکن است در هر زمان تغییر کنند.

تغییریافته در نسخهٔ 3.0: پارامتر و پیکربندی use_native_unicode حذف شد.

تغییریافته در نسخهٔ 2.4: پارامتر engine_options اضافه شد.

تغییریافته در نسخهٔ 2.1: پارامترهای metadata، query_class و model_class اضافه شدند.

تغییریافته در نسخهٔ 2.1: استفاده از کلاس پرس‌وجوی یکسان در سراسر session، Model.query و Query.

تغییریافته در نسخهٔ 0.16: مقدار scopefunc در session_options پذیرفته می‌شود.

تغییریافته در نسخهٔ 0.10: پارامتر session_options اضافه شد.

یک کلاس مدل اعلانی SQLAlchemy. از این کلاس برای تعریف مدل‌های پایگاه داده ارث‌بری کنید.

اگر مدلی __tablename__ را تنظیم نکند، نام جدول با تبدیل نام کلاس از حالت CamelCase به snake_case تولید خواهد شد. چنانچه به نظر برسد که مدل از توارث تک‌جدولی (single-table inheritance) استفاده می‌کند، نام جدول تولید نخواهد شد.

اگر یک مدل یا کلاس والد آن __bind_key__ را تنظیم کند، از متادیتا و موتور پایگاه داده مربوط به آن استفاده خواهد کرد. در غیر این صورت، از metadata و engine پیش‌فرض استفاده می‌کند. اگر مدل metadata یا __table__ را تنظیم کرده باشد، این مقدار نادیده گرفته می‌شود.

برای کدهایی که از API نسخهٔ 1.x ابزار SQLAlchemy استفاده می‌کنند، این مدل را با ارث‌بری از Model و ارسال پارامتر model_class به افزونه سفارشی‌سازی کنید. همچنین می‌توان یک کلاس مدل اعلانی کاملاً ایجاد شده را برای استفاده از متاردهٔ (metaclass) سفارشی ارسال کرد.

برای کدهایی که از API نسخهٔ 2.x ابزار SQLAlchemy استفاده می‌کنند، این مدل را با ارث‌بری از sqlalchemy.orm.DeclarativeBase https://docs.sqlalchemy.org/en/20/orm/mapping_api.html#sqlalchemy.orm.DeclarativeBase یا sqlalchemy.orm.DeclarativeBaseNoMeta https://docs.sqlalchemy.org/en/20/orm/mapping_api.html#sqlalchemy.orm.DeclarativeBaseNoMeta و ارسال پارامتر model_class به افزونه سفارشی‌سازی نمایید.

کلاس پرس‌وجوی پیش‌فرض مورد استفاده در Model.query و رابطه‌های lazy="dynamic".

هشدار:

رابط query در SQLAlchemy یک رابط قدیمی (legacy) در نظر گرفته می‌شود.

این کلاس را با ارسال پارامتر query_class به افزونه سفارشی‌سازی کنید.

یک کلاس sqlalchemy.schema.Table https://docs.sqlalchemy.org/en/20/core/metadata.html#sqlalchemy.schema.Table که متادیتا را به‌صورت خودکار انتخاب می‌کند.

برخلاف کلاس پایهٔ Table، آرگومان metadata الزامی نیست. اگر مشخص نشود، بر اساس آرگومان bind_key انتخاب خواهد شد.

پارامترها (Parameters)
  • bind_key -- برای انتخاب یک متادیتای متفاوت استفاده می‌شود.
  • args -- آرگومان‌های ارسال‌شده به کلاس پایه. این موارد معمولاً نام جدول، ستون‌ها و قیدها (constraints) هستند.
  • kwargs -- آرگومان‌های ارسال‌شده به کلاس پایه.
تغییریافته در نسخهٔ 3.0: این به جای یک تابع، یک زیرکلاس از Table در SQLAlchemy است.
جدول‌هایی که در پایگاه‌داده وجود ندارند را با فراخوانی metadata.create_all() برای همه یا برخی از کلیدهای bind ایجاد می‌کند. این متد جدول‌های موجود را به‌روزرسانی نمی‌کند؛ برای این منظور از یک کتابخانهٔ مهاجرت (migration) استفاده کنید.

این عمل مستلزم فعال بودن یک بافت کاربرد (application context) در Flask است.

پارامترها
bind_key (str https://docs.python.org/3/library/stdtypes.html#str | None | list https://docs.python.org/3/library/stdtypes.html#list[str https://docs.python.org/3/library/stdtypes.html#str | None]) -- یک کلید bind یا فهرستی از کلیدها برای ایجاد جدول‌ها. مقدار پیش‌فرض، همهٔ bindها است.
نوع بازگشتی
None

تغییریافته در نسخهٔ 3.0: نام پارامتر bind به bind_key تغییر یافت. پارامتر app حذف شد.

تغییریافته در نسخهٔ 0.12: پارامترهای bind و app افزوده شدند.

جدول‌ها را با فراخوانی metadata.drop_all() برای همه یا برخی از کلیدهای bind حذف می‌کند.

این عمل مستلزم فعال بودن یک بافت کاربرد (application context) در Flask است.

پارامترها
bind_key (str https://docs.python.org/3/library/stdtypes.html#str | None | list https://docs.python.org/3/library/stdtypes.html#list[str https://docs.python.org/3/library/stdtypes.html#str | None]) -- یک کلید bind یا فهرستی از کلیدها برای حذف جدول‌ها از آن‌ها. مقدار پیش‌فرض، همهٔ bindها است.
نوع بازگشتی
None

تغییریافته در نسخهٔ 3.0: نام پارامتر bind به bind_key تغییر یافت. پارامتر app حذف شد.

تغییریافته در نسخهٔ 0.12: پارامترهای bind و app افزوده شدند.

یک sqlalchemy.orm.dynamic_loader() https://docs.sqlalchemy.org/en/20/orm/relationship_api.html#sqlalchemy.orm.dynamic_loader که کلاس Query این افزونه را برای رابطه‌ها و backrefها اعمال می‌کند.

تغییریافته در نسخهٔ 3.0: کلاس Query روی backref تنظیم می‌شود.

موتور پیش‌فرض (Engine https://docs.sqlalchemy.org/en/20/core/connections.html#sqlalchemy.engine.Engine) برای برنامهٔ فعلی، که در صورت عدم تنظیم کلید bind برای Model یا Table مورد پرس‌وجو، توسط session استفاده می‌شود.

برای سفارشی‌سازی، پیکربندی SQLALCHEMY_ENGINE_OPTIONS <#flask_sqlalchemy.config.SQLALCHEMY_ENGINE_OPTIONS> را تنظیم کرده و مقادیر پیش‌فرض را با ارسال پارامتر engine_options به افزونه مشخص کنید.

این عمل مستلزم فعال بودن یک بافت کاربرد (application context) در Flask است.

نگاشتی از کلیدهای bind به نمونه‌های sqlalchemy.engine.Engine https://docs.sqlalchemy.org/en/20/core/connections.html#sqlalchemy.engine.Engine برای برنامهٔ فعلی. کلید None به موتور پیش‌فرض اشاره دارد و به صورت engine در دسترس است.

برای سفارشی‌سازی، پیکربندی SQLALCHEMY_BINDS <#flask_sqlalchemy.config.SQLALCHEMY_BINDS> را تنظیم کرده و مقادیر پیش‌فرض را با ارسال پارامتر engine_options به افزونه مشخص کنید.

این عمل مستلزم فعال بودن یک بافت کاربرد (application context) در Flask است.

افزوده‌شده در نسخهٔ 3.0.

مشابه Result.scalar() https://docs.sqlalchemy.org/en/20/core/connections.html#sqlalchemy.engine.Result.scalar، اما به جای بازگرداندن None، با خطای 404 Not Found متوقف می‌شود.
پارامترها
نوع بازگشتی
Any https://docs.python.org/3/library/typing.html#typing.Any

افزوده‌شده در نسخهٔ 3.0.

موتور مربوط به کلید bind ارائه‌شده را برای برنامهٔ فعلی دریافت می‌کند. این عمل مستلزم فعال بودن یک بافت کاربرد (application context) در Flask است.

منسوخ‌شده از نسخهٔ 3.0: در Flask-SQLAlchemy 3.2 حذف خواهد شد. به جای آن از engines[key] استفاده کنید.

تغییریافته در نسخهٔ 3.0: نام پارامتر bind به bind_key تغییر یافت. پارامتر app حذف شد.

مشابه session.get() https://docs.sqlalchemy.org/en/20/orm/session_api.html#sqlalchemy.orm.Session.get، اما به جای بازگرداندن None، با خطای 404 Not Found متوقف می‌شود.
پارامترها
نوع بازگشتی
_O

تغییریافته در نسخهٔ 3.1: ارسال آرگومان‌های کلیدواژه‌ای اضافی به session.get().

افزوده‌شده در نسخهٔ 3.0.

راه‌اندازی یک برنامهٔ Flask جهت استفاده با نمونهٔ این افزونه. این متد باید قبل از دسترسی به موتور یا session پایگاه‌داده با برنامه فراخوانی شود..sp این متد مقادیر پیکربندی پیش‌فرض را تعیین می‌کند، سپس افزونه را روی برنامه پیکربندی کرده و موتورها (engines) را برای هر bind key ایجاد می‌نماید. بنابراین، این متد باید پس از پیکربندی برنامه فراخوانی شود. تغییرات اعمال‌شده در پیکربندی برنامه پس از این فراخوانی منعکس نخواهند شد.

کلیدهای زیر از app.config استفاده می‌شوند:

  • SQLALCHEMY_DATABASE_URI <#flask_sqlalchemy.config.SQLALCHEMY_DATABASE_URI>
  • SQLALCHEMY_ENGINE_OPTIONS <#flask_sqlalchemy.config.SQLALCHEMY_ENGINE_OPTIONS>
  • SQLALCHEMY_ECHO <#flask_sqlalchemy.config.SQLALCHEMY_ECHO>
  • SQLALCHEMY_BINDS <#flask_sqlalchemy.config.SQLALCHEMY_BINDS>
  • SQLALCHEMY_RECORD_QUERIES <#flask_sqlalchemy.config.SQLALCHEMY_RECORD_QUERIES>
  • SQLALCHEMY_TRACK_MODIFICATIONS <#flask_sqlalchemy.config.SQLALCHEMY_TRACK_MODIFICATIONS>
پارامترها (Parameters)
app (Flask https://flask.palletsprojects.com/en/stable/api/#flask.Flask) -- برنامهٔ Flask برای مقداردهی اولیه.
نوع بازگشتی (Return type)
None
متادیتای پیش‌فرض مورداستفاده توسط Model و Table در صورتی که هیچ bind key تعیین نشده باشد.
نگاشت bind keyها به نمونه‌های sqlalchemy.schema.MetaData https://docs.sqlalchemy.org/en/20/core/metadata.html#sqlalchemy.schema.MetaData. کلید None به متادیتای پیش‌فرض اشاره دارد و به صورت metadata در دسترس است.

متادیتای پیش‌فرض را با ارسال پارامتر metadata به افزونه سفارشی‌سازی کنید. این کار می‌تواند برای تنظیم یک قرارداد نام‌گذاری (naming convention) استفاده شود. هنگامی که متادیتا برای یک bind key دیگر ایجاد می‌شود، قرارداد نام‌گذاری پیش‌فرض را کپی می‌کند.

اضافه‌شده در نسخه 3.0.

مانند Result.scalar_one() https://docs.sqlalchemy.org/en/20/core/connections.html#sqlalchemy.engine.Result.scalar_one است، اما به جای برانگیختن خطای NoResultFound یا MultipleResultsFound، با یک خطای 404 Not Found عملیات را متوقف می‌کند.
پارامترها (Parameters)
نوع بازگشتی (Return type)
Any https://docs.python.org/3/library/typing.html#typing.Any

اضافه‌شده در نسخه 3.0.

یک offset و limit را بر اساس صفحهٔ فعلی و تعداد آیتم‌ها در هر صفحه بر روی یک عبارت select اعمال می‌کند و یک شیء Pagination را بازمی‌گرداند.

عبارت باید یک کلاس مدل را انتخاب کند، مانند select(User). این کار اصلاح‌کننده‌های unique() و scalars() را روی نتیجه اعمال می‌کند، بنابراین selectهای مرکب نتایج مورد انتظار را بازنخواهند گرداند.

پارامترها (Parameters)
  • select (Select https://docs.sqlalchemy.org/en/20/core/selectable.html#sqlalchemy.sql.expression.Select) -- عبارت select برای صفحه‌بندی.
  • page (int https://docs.python.org/3/library/functions.html#int | None) -- صفحهٔ فعلی، مورداستفاده برای محاسبهٔ offset. در طول یک درخواست، پیش‌فرض آرگومان پرس‌وجوی page است، در غیر این صورت 1 است.
  • per_page (int https://docs.python.org/3/library/functions.html#int | None) -- حداکثر تعداد آیتم‌ها در یک صفحه، مورداستفاده برای محاسبهٔ offset و limit. در طول یک درخواست، پیش‌فرض آرگومان پرس‌وجوی per_page است، در غیر این صورت 20 است.
  • max_per_page (int https://docs.python.org/3/library/functions.html#int | None) -- حداکثر مقدار مجاز برای per_page، جهت محدود کردن مقدار ارائه‌شده توسط کاربر. برای عدم اعمال محدودیت از None استفاده کنید. پیش‌فرض 100 است.
  • error_out (bool https://docs.python.org/3/library/functions.html#bool) -- توقف با خطای 404 Not Found اگر هیچ آیتمی برگردانده نشود و page برابر 1 نباشد، یا اگر page یا per_page کمتر از 1 باشند، یا اگر هیچ‌کدام عدد صحیح نباشند.
  • count (bool https://docs.python.org/3/library/functions.html#bool) -- محاسبهٔ تعداد کل مقادیر با اجرای یک پرس‌وجوی count اضافی. برای پرس‌وجوهای بسیار پیچیده ممکن است این کار نادرست یا کند باشد، بنابراین در صورت نیاز می‌تواند غیرفعال شده و به صورت دستی تنظیم شود.
نوع بازگشتی (Return type)
Pagination <#flask_sqlalchemy.pagination.Pagination>

تغییریافته در نسخه 3.0: پرس‌وجوی count کارآمدتر شده است.

اضافه‌شده در نسخه 3.0.

بارگذاری تعاریف جدول‌ها از پایگاه داده با فراخوانی metadata.reflect() برای همه یا برخی از bind keyها.

این نیازمند فعال بودن کانتکست برنامهٔ Flask (application context) است.

پارامترها (Parameters)
bind_key (str https://docs.python.org/3/library/stdtypes.html#str | None | list https://docs.python.org/3/library/stdtypes.html#list[str https://docs.python.org/3/library/stdtypes.html#str | None]) -- یک bind key یا فهرستی از کلیدها برای بازتاب (reflect) جدول‌ها از آن. پیش‌فرض همهٔ bindها است.
نوع بازگشتی (Return type)
None

تغییریافته در نسخه 3.0: تغییر نام پارامتر bind به bind_key. پارامتر app حذف شد.

تغییریافته در نسخه 0.12: پارامترهای bind و app اضافه شدند.

یک sqlalchemy.orm.relationship() https://docs.sqlalchemy.org/en/20/orm/relationship_api.html#sqlalchemy.orm.relationship که کلاس Query این افزونه را برای روابط پویا و backrefها اعمال می‌کند.

تغییریافته در نسخه 3.0: کلاس Query روی backref تنظیم می‌شود.

یک sqlalchemy.orm.scoping.scoped_session https://docs.sqlalchemy.org/en/20/orm/contextual.html#sqlalchemy.orm.scoped_session که نمونه‌هایی از Session را با محدودهٔ کانتکست فعلی برنامهٔ Flask ایجاد می‌کند. این نشست هنگام خروج از کانتکست برنامه حذف خواهد شد و اتصال موتور به استخر (pool) بازگردانده می‌شود.

این مورد را با ارسال session_options به افزونه سفارشی‌سازی کنید.

این نیازمند فعال بودن کانتکست برنامهٔ Flask است.

تغییریافته در نسخه 3.0: نشست در محدودهٔ کانتکست برنامهٔ فعلی تعریف می‌شود.

کلاس پایه برای کلاس مدل اعلانی SQLAlchemy.Model.

برای تعریف مدل‌ها، از db.Model مشتق بگیرید، نه از این کلاس. برای سفارشی‌سازی db.Model، از این کلاس ارث‌بری کرده و آن را به عنوان model_class به SQLAlchemy ارسال کنید. برای سفارشی‌سازی db.Model در سطح متاکلاس، یک کلاس مدل اعلانی که از قبل ایجاد شده را به عنوان model_class ارسال کنید.

__bind_key__
از این کلید پیوند (bind key) برای انتخاب متادیتا و موتوری که به جدول این مدل مرتبط می‌شوند استفاده کنید. در صورت تنظیم metadata یا __table__ نادیده گرفته می‌شود. در صورت ارائه نشدن، از کلید پیش‌فرض، یعنی None، استفاده خواهد شد.
__tablename__
نام جدول در پایگاه داده. این مورد توسط SQLAlchemy الزامی است؛ هرچند Flask-SQLAlchemy در صورتی که برای مدلی یک کلید اصلی تعریف شده باشد، آن را به‌طور خودکار تنظیم خواهد کرد. اگر __table__ یا __tablename__ به‌طور صریح تنظیم شوند، همان مقدار به کار گرفته می‌شود.
یک پرس‌وجوی SQLAlchemy برای مدل. معادل با db.session.query(Model). می‌تواند برای هر مدل با بازنویسی query_class سفارشی‌سازی شود.

هشدار:

رابط پرس‌وجو (query interface) در SQLAlchemy یک قابلیت قدیمی (legacy) به شمار می‌رود. ترجیحاً به جای آن از session.execute(select()) استفاده کنید.
کلاس پرس‌وجو که توسط query استفاده می‌شود. پیش‌فرض آن SQLAlchemy.Query است که خود به طور پیش‌فرض روی Query قرار دارد.

نام مستعار Query

اگر کد شما از API نگارش SQLAlchemy 1.x استفاده می‌کند (حالت پیش‌فرض برای کدهایی که model_class را مشخص نکرده‌اند)، در این صورت این میکس‌این‌ها به‌طور خودکار روی کلاس Model اعمال می‌شوند.

متاکلاس اعلانی SQLAlchemy که پشتیبانی از __bind_key__ و __tablename__ را فراهم می‌کند.
میکس‌این متاکلاس که metadata یک مدل را بر اساس __bind_key__ آن تنظیم می‌کند.

اگر مدل مستقیماً metadata یا __table__ را تنظیم کند، __bind_key__ نادیده گرفته می‌شود. اگر metadata با مدل والد یکسان باشد، مستقیماً روی مدل فرزند تنظیم نخواهد شد.

میکس‌این متاکلاس که __tablename__ یک مدل را با تبدیل نام کلاس از CamelCase به snake_case تنظیم می‌کند. برای مدل‌های غیرانتزاعی (non-abstract) که مشخصاً نامی تعیین نکرده‌اند، __tablename__ تنظیم می‌شود. اگر یک مدل کلید اصلی تعریف نکرده باشد، به منظور وراثت تک‌جدولی (single-table inheritance)، نام یا __table__ تولید نخواهد شد.
یک کلاس Session https://docs.sqlalchemy.org/en/20/orm/session_api.html#sqlalchemy.orm.Session از SQLAlchemy که موتور (engine) مورد استفاده را بر اساس bind key مرتبط با متادیتای شیءِ در حال پرس‌وجو، انتخاب می‌کند.

برای سفارشی‌سازی db.session، از این کلاس زیرکلاس بسازید و آن را به عنوان کلید class_ در session_options به SQLAlchemy ارسال کنید.

تغییریافته در نسخهٔ 3.0: نام آن از SignallingSession تغییر یافت.

پارامترها (Parameters)
  • db (SQLAlchemy <#flask_sqlalchemy.SQLAlchemy>)
  • kwargs (t.Any)
یک engine را بر اساس bind_key متادیتای مرتبط با مدل یا جدولِ در حال پرس‌وجو انتخاب می‌کند. اگر هیچ bind keyای تنظیم نشده باشد، از bind پیش‌فرض استفاده می‌کند.

تغییریافته در نسخهٔ 3.0.3: رفع مشکل پیدا کردن bind برای یک مدل با ارث‌بری پیوسته (joined inheritance).

تغییریافته در نسخهٔ 3.0: پیاده‌سازی بیش از پیش با پیاده‌سازی پایهٔ SQLAlchemy منطبق شده است.

تغییریافته در نسخهٔ 2.1: پشتیبانی از پیوستن به یک تراکنش (transaction) خارجی.

برشی از کل آیتم‌های یک پرس‌وجو که با اعمال offset و limit بر اساس صفحهٔ جاری و تعداد آیتم‌ها در هر صفحه به دست می‌آید.

اشیاء صفحه‌بندی را به صورت دستی ایجاد نکنید. آن‌ها توسط SQLAlchemy.paginate() و Query.paginate() ایجاد می‌شوند.

تغییریافته در نسخهٔ 3.0: پیمایش روی یک شیء صفحه‌بندی، روی آیتم‌های آن پیمایش می‌کند.

تغییریافته در نسخهٔ 3.0: ایجاد نمونه‌ها به صورت دستی، یک رابط برنامه‌نویسی عمومی (public API) نیست.

حداکثر تعداد آیتم‌ها در یک صفحه.
آیتم‌های موجود در صفحهٔ جاری. پیمایش روی شیء صفحه‌بندی معادل پیمایش روی این آیتم‌ها است.
شمارهٔ نخستین آیتم در صفحه، با شروع از ۱، یا ۰ در صورتی که هیچ آیتمی وجود نداشته باشد.

اضافه شده در نسخهٔ 3.0.

شمارهٔ آخرین آیتم در صفحه، با شروع از ۱ (شامل خود آن)، یا ۰ در صورتی که هیچ آیتمی وجود نداشته باشد.

اضافه شده در نسخهٔ 3.0.

برابر با True اگر این صفحه، صفحهٔ نخست نباشد.
شمارهٔ صفحهٔ پیشین، یا None اگر این صفحه، صفحهٔ نخست باشد.
پرس‌وجوی شیء Pagination برای صفحهٔ پیشین.
پارامترها (Parameters)
error_out (bool https://docs.python.org/3/library/functions.html#bool) -- توقف عملیات با خطای 404 Not Found اگر هیچ آیتمی برگردانده نشود و page برابر ۱ نباشد، یا اگر page یا per_page کمتر از ۱ باشند، یا اگر هیچ‌کدام عدد صحیح (int) نباشند.
نوع بازگشتی (Return type)
Pagination <#flask_sqlalchemy.pagination.Pagination>
برابر با True اگر این صفحه، صفحهٔ پایانی نباشد.
شمارهٔ صفحهٔ بعدی، یا None اگر این صفحه، صفحهٔ پایانی باشد.
پرس‌وجوی شیء Pagination برای صفحهٔ بعدی.
پارامترها (Parameters)
error_out (bool https://docs.python.org/3/library/functions.html#bool) -- توقف عملیات با خطای 404 Not Found اگر هیچ آیتمی برگردانده نشود و page برابر ۱ نباشد، یا اگر page یا per_page کمتر از ۱ باشند، یا اگر هیچ‌کدام عدد صحیح (int) نباشند.
نوع بازگشتی (Return type)
Pagination <#flask_sqlalchemy.pagination.Pagination>
تولید شماره‌های صفحه برای یک ویجت صفحه‌بندی. صفحه‌های رد شده میان لبه‌ها و بخش میانی با None نشان داده می‌شوند.

برای مثال، اگر ۲۰ صفحه وجود داشته باشد و صفحهٔ جاری ۷ باشد، مقادیر زیر تولید می‌شوند.

1, 2, None, 5, 6, 7, 8, 9, 10, 11, None, 19, 20
پارامترها
نوع بازگشتی
Iterator https://docs.python.org/3/library/typing.html#typing.Iterator[int https://docs.python.org/3/library/functions.html#int | None]

تغییر در نسخهٔ 3.0: بهبود کارایی در محاسبهٔ مقادیری که باید yield شوند.

تغییر در نسخهٔ 3.0: مرز right_current فراگیر (inclusive) است.

تغییر در نسخهٔ 3.0: همهٔ پارامترها فقط کلیدواژه‌ای (keyword-only) هستند.

زیرکلاسی از Query در SQLAlchemy https://docs.sqlalchemy.org/en/20/orm/queryguide/query.html#sqlalchemy.orm.Query به همراه چند متد اضافی که برای پرس‌وجو در یک برنامهٔ کاربردی وب مفید هستند.

این کلاس پرس‌وجوی پیش‌فرض برای Model.query است.

تغییر در نسخهٔ 3.0: از BaseQuery به Query تغییر نام یافت.

پارامترها
  • entities (Union[_ColumnsClauseArgument[Any], Sequence[_ColumnsClauseArgument[Any]]])
  • session (Optional[Session <#flask_sqlalchemy.session.Session>])
مشابه first() https://docs.sqlalchemy.org/en/20/orm/queryguide/query.html#sqlalchemy.orm.Query.first است اما به جای بازگرداندن None، با خطای 404 Not Found عملیات را لغو می‌کند.
پارامترها
description (str https://docs.python.org/3/library/stdtypes.html#str | None) -- یک پیام سفارشی برای نمایش در صفحهٔ خطا.
نوع بازگشتی
Any https://docs.python.org/3/library/typing.html#typing.Any
مشابه get() https://docs.sqlalchemy.org/en/20/orm/queryguide/query.html#sqlalchemy.orm.Query.get است اما به جای بازگرداندن None، با خطای 404 Not Found عملیات را لغو می‌کند.
پارامترها
نوع بازگشتی
Any https://docs.python.org/3/library/typing.html#typing.Any
مشابه one() https://docs.sqlalchemy.org/en/20/orm/queryguide/query.html#sqlalchemy.orm.Query.one است اما به جای ایجاد استثنای NoResultFound یا MultipleResultsFound، با خطای 404 Not Found عملیات را لغو می‌کند.
پارامترها
description (str https://docs.python.org/3/library/stdtypes.html#str | None) -- یک پیام سفارشی برای نمایش در صفحهٔ خطا.
نوع بازگشتی
Any https://docs.python.org/3/library/typing.html#typing.Any

افزوده شده در نسخهٔ 3.0.

بر اساس صفحهٔ جاری و تعداد موارد در هر صفحه، یک offset و limit بر پرس‌وجو اعمال می‌کند و یک شیء Pagination برمی‌گرداند.
پارامترها
  • page (int https://docs.python.org/3/library/functions.html#int | None) -- صفحهٔ جاری که برای محاسبهٔ offset استفاده می‌شود. در طول یک درخواست، پیش‌فرض آن آرگومان پرس‌وجوی page و در غیر این صورت 1 است.
  • per_page (int https://docs.python.org/3/library/functions.html#int | None) -- حداکثر تعداد موارد در یک صفحه که برای محاسبهٔ offset و limit استفاده می‌شود. در طول یک درخواست، پیش‌فرض آن آرگومان پرس‌وجوی per_page و در غیر این صورت 20 است.
  • max_per_page (int https://docs.python.org/3/library/functions.html#int | None) -- حداکثر مقدار مجاز برای per_page، جهت محدود کردن مقدار ارائه‌شده توسط کاربر. برای نداشتن محدودیت از None استفاده کنید. پیش‌فرض 100 است.
  • error_out (bool https://docs.python.org/3/library/functions.html#bool) -- در صورتی که هیچ موردی برگردانده نشود و page برابر 1 نباشد، یا اگر page یا per_page کمتر از 1 باشند، یا اگر هر کدام int نباشند، با خطای 404 Not Found عملیات را متوقف می‌کند.
  • count (bool https://docs.python.org/3/library/functions.html#bool) -- تعداد کل مقادیر را با اجرای یک پرس‌وجوی count اضافی محاسبه می‌کند. برای پرس‌وجوهای بسیار پیچیده این مقدار ممکن است نادقیق یا کند باشد، از این رو می‌توان در صورت نیاز آن را غیرفعال کرد و به صورت دستی مقداردهی نمود.
نوع بازگشتی
Pagination <#flask_sqlalchemy.pagination.Pagination>

تغییر در نسخهٔ 3.0: همهٔ پارامترها فقط کلیدواژه‌ای (keyword-only) هستند.

تغییر در نسخهٔ 3.0: پرس‌وجوی count کارآمدتر شده است.

تغییر در نسخهٔ 3.0: پیش‌فرض max_per_page برابر با 100 است.

فهرست اطلاعات پرس‌وجوهای ثبت‌شده برای نشست (session) فعلی را دریافت می‌کند. پرس‌وجوها در صورتی ثبت می‌شوند که پیکربندی SQLALCHEMY_RECORD_QUERIES <#flask_sqlalchemy.config.SQLALCHEMY_RECORD_QUERIES> فعال باشد.

هر شیء اطلاعات پرس‌وجو دارای مشخصه‌های زیر است:

رشتهٔ SQL تولیدشده توسط SQLAlchemy به همراه جای‌نگهدارنده‌های پارامتر.
پارامترهای ارسال‌شده به همراه عبارت SQL.
اطلاعات زمان‌بندی دربارهٔ زمان آغاز اجرای پرس‌وجو و زمان بازگشت نتایج. دقت و مقدار آن به سیستم‌عامل بستگی دارد.
مدت‌زمان اجرای پرس‌وجو به ثانیه.
توضیحی رشته‌ای از مکانی در کد برنامهٔ شما که پرس‌وجو در آن اجرا شده است. ممکن است محاسبهٔ این مورد امکان‌پذیر نباشد و قالب آن پایدار نیست.

تغییریافته در نسخهٔ 3.0: تغییر نام از get_debug_queries.

تغییریافته در نسخهٔ 3.0: شیء اطلاعات به جای یک تاپل یک dataclass است.

تغییریافته در نسخهٔ 3.0: مشخصهٔ context در شیء اطلاعات به location تغییر نام یافته است.

تغییریافته در نسخهٔ 3.0: در حالت اشکال‌زدایی یا آزمایش به‌طور خودکار فعال نمی‌شود.

نوع بازگشتی (Return type)
list https://docs.python.org/3/library/stdtypes.html#list[_QueryInfo]

این سیگنال Blinker پس از اعمال (commit) نشست در صورتی که مدل‌های تغییریافته‌ای در نشست وجود داشته باشند، ارسال می‌شود.

ارسال‌کننده برنامهٔ کاربردی است که تغییرات را صادر کرده است. به دریافت‌کننده آرگومان changes به همراه فهرستی از تاپل‌ها به صورت (instance, operation) فرستاده می‌شود. عملیات‌ها عبارت‌اند از "insert"، "update" و "delete".

این سیگنال دقیقاً مانند models_committed عمل می‌کند اما قبل از انجام commit صادر می‌شود.

کپی‌رایت 2010 Pallets

توزیع مجدد و استفاده به اشکال سورس و باینری، با یا بدون تغییر، مجاز است به شرطی که شرایط زیر رعایت شوند:

1.
توزیع‌های مجدد سورس‌کد باید اعلان کپی‌رایت بالا، این فهرست شرایط و سلب مسئولیت زیر را حفظ کنند.
2.
توزیع‌های مجدد در قالب باینری باید اعلان کپی‌رایت بالا، این فهرست شرایط و سلب مسئولیت زیر را در مستندات و/یا سایر موادی که همراه با توزیع ارائه می‌شوند بازتولید کنند.
3.
نه نام دارندهٔ کپی‌رایت و نه نام مشارکت‌کنندگان آن نباید برای تأیید یا تبلیغ محصولات برگرفته از این نرم‌افزار بدون اجازهٔ کتبی قبلی استفاده شود.

این نرم‌افزار توسط دارندگان کپی‌رایت و مشارکت‌کنندگان به‌صورت «همان‌گونه که هست» ("AS IS") ارائه می‌شود و هرگونه ضمانت صریح یا ضمنی، شامل، اما نه محدود به، ضمانت‌های ضمنی قابلیت خریدوفروش و مناسب بودن برای یک هدف خاص سلب می‌شود. در هیچ حالتی دارندهٔ کپی‌رایت یا مشارکت‌کنندگان در قبال خسارت‌های مستقیم، غیرمستقیم، اتفاقی، خاص، تنبیهی یا تبعی (شامل، اما نه محدود به تهیهٔ کالاها یا خدمات جایگزین؛ عدم امکان استفاده، از دست رفتن داده‌ها یا سود؛ یا وقفه در کسب‌وکار) به هر نحوی که ایجاد شده باشد و بر پایهٔ هر فرضیهٔ مسئولیتی، چه در قرارداد، مسئولیت مدنی یا شبه‌جرم (شامل اهمال یا موارد دیگر) ناشی از استفاده از این نرم‌افزار مسئول نخواهند بود، حتی در صورتی که احتمال وقوع چنین خسارتی اطلاع داده شده باشد..SS "تغییرات (Changes)"

منتشر شده در 2023-09-11

•
ویژگی __version__ منسوخ شد. در عوض، از تشخیص ویژگی یا importlib.metadata.version("flask-sqlalchemy") استفاده کنید. #5230 https://github.com/pallets-eco/flask-sqlalchemy/issues/5230

منتشر شده در 2023-09-11

منتشر شده در 2023-06-21

منتشر شده در 2023-06-19

منتشر شده در 2023-01-31

منتشر شده در 2022-10-14

•
به‌روزرسانی سازگاری با SQLAlchemy 2. #1122 https://github.com/pallets-eco/flask-sqlalchemy/issues/1122

منتشر شده در 2022-10-11

منتشر شده در 2022-10-04

  • پایان پشتیبانی از Python 2، 3.4، 3.5 و 3.6.
  • افزایش حداقل نسخه Flask به 2.2.
  • افزایش حداقل نسخه SQLAlchemy به 1.4.18.
  • حذف کدهای از پیش منسوخ‌شده.
  • محدوده نشست (session) اکنون به‌جای thread، به بافت فعلی برنامه (app context) مقید است. این امر نیازمند فعال بودن یک app context است و تضمین می‌کند که session پس از هر درخواست پاک‌سازی می‌شود.
  • برای دسترسی به session و engine، صرف‌نظر از اینکه برنامه‌ای به سازنده داده شده باشد یا خیر، همواره یک بافت فعال برنامه Flask مورد نیاز است. #508 https://github.com/pallets-eco/flask-sqlalchemy/issues/508#944 https://github.com/pallets-eco/flask-sqlalchemy/issues/944
  • کلیدهای bind مختلف از ثبات‌های MetaData متفاوت در SQLAlchemy استفاده می‌کنند، که امکان هم‌نام بودن جدول‌ها در پایگاه‌های داده مختلف را فراهم می‌سازد. کلیدهای bind به‌جای مدل یا جدول، روی متادیتای حاصل ذخیره و بازیابی می‌شوند.
  • مقدار SQLALCHEMY_DATABASE_URI به‌طور پیش‌فرض به sqlite:///:memory: تنظیم نمی‌شود. اگر نه این گزینه و نه SQLALCHEMY_BINDS هیچ engineای را تعریف نکنند، خطایی صادر می‌شود. #731 https://github.com/pallets-eco/flask-sqlalchemy/pull/731
  • پیکربندی SQLite با یک مسیر نسبی، نسبت به app.instance_path سنجیده می‌شود و نه app.root_path. در صورت لزوم، پوشه instance ایجاد می‌شود. #462 https://github.com/pallets-eco/flask-sqlalchemy/issues/462
  • افزوده شدن متدهای get_or_404، first_or_404، one_or_404 و paginate به شیء افزونه. این‌ها به‌جای رابط قدیمی query، از الگوی ترجیحی SQLAlchemy یعنی session.execute(select()) استفاده می‌کنند. #1088 https://github.com/pallets-eco/flask-sqlalchemy/issues/1088
  • متدهای راه‌اندازی که engineها و session را ایجاد می‌کنند، با یک خط زیر (underscore) در ابتدا تغییر نام یافته‌اند. این متدها رابط‌های داخلی محسوب شده و ممکن است در هر زمانی تغییر کنند.
  • تمام پارامترهای SQLAlchemy به‌جز app صرفاً به‌صورت کلیدواژه‌ای هستند.
  • تغییر نام پارامتر bind به bind_key و حذف پارامتر app از متدهای مختلف SQLAlchemy.
  • شیء افزونه به‌جای رونوشت‌برداری از نام‌ها به‌عنوان ویژگی، از __getattr__ برای نام‌های مستعار از بسته SQLAlchemy استفاده می‌کند.
  • شیء افزونه مستقیماً به‌صورت app.extensions["sqlalchemy"] ذخیره می‌شود. #698 https://github.com/pallets-eco/flask-sqlalchemy/issues/698
  • کلاس نشست می‌تواند با ارسال کلید class_ در پارامتر session_options سفارشی‌سازی شود. #327 https://github.com/pallets-eco/flask-sqlalchemy/issues/327
  • نام SignallingSession به Session تغییر یافت.
  • متد Session.get_bind تطابق بیشتری با پیاده‌سازی پایه دارد.
  • کلاس‌های مدل و نمونه db بدون نیاز به واردسازی (import) در flask shell در دسترس هستند. #1089 https://github.com/pallets-eco/flask-sqlalchemy/issues/1089
  • تبدیل‌کننده نام جدول از CamelCase به snake_case الگوهای بیشتری را به‌درستی مدیریت می‌کند. اگر مدلی که پیش‌تر در پایگاه داده ایجاد شده بود تغییر کرده باشد، یا از Alembic برای تغییر نام جدول استفاده کنید، یا __tablename__ را تنظیم نمایید تا نام قبلی حفظ شود. #406 https://github.com/pallets-eco/flask-sqlalchemy/issues/406
  • خروجی repr در Model بین نمونه‌های گذرا (transient) و در انتظار (pending) تفاوت قائل می‌شود. #967 https://github.com/pallets-eco/flask-sqlalchemy/issues/967
  • یک کلاس مدل سفارشی می‌تواند __init_subclass__ را به همراه پارامترهای کلاس پیاده‌سازی کند. #1002 https://github.com/pallets-eco/flask-sqlalchemy/issues/1002
  • ویژگی db.Table به‌جای تابع، یک زیرکلاس است.
  • پارامتر engine_options پیش از اعمال پیکربندی اختصاصی هر موتور به‌صورت مقادیر پیش‌فرض اعمال می‌شود.
  • مقادیر SQLALCHEMY_BINDS برای هر bind می‌توانند یک URL موتور یا یک دیکشنری از گزینه‌های موتور شامل URL باشند. متغیرهای SQLALCHEMY_DATABASE_URI و SQLALCHEMY_ENGINE_OPTIONS متناظر با کلید None هستند و اولویت دارند. #783 https://github.com/pallets-eco/flask-sqlalchemy/issues/783
  • موتورها به‌هنگام فراخوانی init_app ایجاد می‌شوند، نه در نخستین باری که به آن‌ها دسترسی پیدا می‌شود. #698 https://github.com/pallets-eco/flask-sqlalchemy/issues/698
  • ویژگی db.engines نگاشت کلیدهای bind به موتورها را برای برنامه فعلی در دسترس قرار می‌دهد.
  • متدهای get_engine، get_tables_for_bind و get_binds منسوخ شده‌اند.
  • شناسه‌های URI در سطح درایور SQLite که شبیه به sqlite:///file:name.db?uri=true هستند پشتیبانی می‌شوند. #998 https://github.com/pallets-eco/flask-sqlalchemy/issues/998#1045 https://github.com/pallets-eco/flask-sqlalchemy/issues/1045
  • موتورهای SQLite اگر pool_size برابر با 0 باشد از NullPool استفاده نمی‌کنند.
  • موتورهای MySQL به‌طور پیش‌فرض از مجموعه نویسه "utf8mb4" استفاده می‌کنند. #875 https://github.com/pallets-eco/flask-sqlalchemy/issues/875
  • موتورهای MySQL مقدار pool_size را روی 10 تنظیم نمی‌کنند.
  • موتورهای MySQL در صورت عدم استفاده از queue pool، مقدار پیش‌فرضی برای pool_recycle تعیین نمی‌کنند. #803 https://github.com/pallets-eco/flask-sqlalchemy/issues/803
  • نام BaseQuery به Query تغییر یافت.
  • متد Query.one_or_404 افزوده شد.
  • کلاس query بر روی backref در relationship اعمال می‌شود. #417 https://github.com/pallets-eco/flask-sqlalchemy/issues/417
  • ایجاد دستی اشیاء Pagination دیگر یک API عمومی نیست. آن‌ها باید توسط db.paginate یا query.paginate ایجاد شوند. #1088 https://github.com/pallets-eco/flask-sqlalchemy/issues/1088.IP • 2 پارامترهای Pagination.iter_pages و Query.paginate تنها به‌صورت کلیدواژه‌ای (keyword-only) هستند.
  • کلاس Pagination قابل‌پیمایش (iterable) است و بر روی آیتم‌های خود پیمایش می‌کند. #70 https://github.com/pallets-eco/flask-sqlalchemy/issues/70
  • پرس‌وجوی شمارش صفحه‌بندی بهینه‌تر شده است.
  • متد Pagination.iter_pages بهینه‌تر شده است. #622 https://github.com/pallets-eco/flask-sqlalchemy/issues/622
  • پارامتر right_current در Pagination.iter_pages فراگیر (inclusive) است.
  • مقدار per_page در صفحه‌بندی نمی‌تواند 0 باشد. #1091 https://github.com/pallets-eco/flask-sqlalchemy/issues/1091
  • مقدار پیش‌فرض max_per_page در صفحه‌بندی 100 است. #1091 https://github.com/pallets-eco/flask-sqlalchemy/issues/1091
  • ویژگی‌های Pagination.first و last اضافه شدند که شماره اولین و آخرین آیتم صفحه را ارائه می‌دهند. #567 https://github.com/pallets-eco/flask-sqlalchemy/issues/567
  • متغیر SQLALCHEMY_RECORD_QUERIES به‌طور پیش‌فرض غیرفعال است و با app.debug یا app.testing به‌طور خودکار فعال نمی‌شود. #1092 https://github.com/pallets-eco/flask-sqlalchemy/issues/1092
  • نام get_debug_queries به get_recorded_queries تغییر یافت تا با پیکربندی و عملکرد همخوانی بهتری داشته باشد.
  • اطلاعات پرس‌وجوهای ضبط‌شده اکنون به جای یک tuple، یک dataclass است. مشخصه context به location تغییر نام یافته است. یافتن مکان از بررسی جامع‌تری استفاده می‌کند.
  • متغیر SQLALCHEMY_TRACK_MODIFICATIONS به‌طور پیش‌فرض غیرفعال است. #727 https://github.com/pallets-eco/flask-sqlalchemy/pull/727
  • متغیر SQLALCHEMY_COMMIT_ON_TEARDOWN منسوخ شده است. این متغیر می‌تواند باعث مشکلات گوناگون طراحی شود که اشکال‌زدایی آن‌ها دشوار است. در عوض مستقیماً db.session.commit() را فراخوانی کنید. #216 https://github.com/pallets-eco/flask-sqlalchemy/issues/216

منتشرشده در 2021-03-18

•
رفع مشکل سازگاری با Python 2.7.

منتشرشده در 2021-03-18

  • به‌روزرسانی برای پشتیبانی از SQLAlchemy 1.4.
  • اشیاء URL در SQLAlchemy تغییرناپذیر هستند. برخی از متدهای داخلی تغییر یافته‌اند تا به جای None، یک URL جدید بازگردانند. #885 https://github.com/pallets-eco/flask-sqlalchemy/issues/885

منتشرشده در 2020-07-14

•
تغییر کلاس پایه mixinهای متا به type. این تغییر مشکلی را که در اثر پس‌رفت در CPython 3.8.4 ایجاد شده بود برطرف می‌کند. #852 https://github.com/pallets-eco/flask-sqlalchemy/issues/852

منتشرشده در 2020-05-26

•
منسوخ شدن SQLALCHEMY_COMMIT_ON_TEARDOWN به دلیل اینکه می‌تواند باعث مشکلات گوناگون طراحی شود که اشکال‌زدایی آن‌ها دشوار است. در عوض مستقیماً db.session.commit() را فراخوانی کنید. #216 https://github.com/pallets-eco/flask-sqlalchemy/issues/216

منتشرشده در 2020-05-25

•
رفع مشکل صفحه‌بندی نادرست در زمان یکتا‌سازی (de-duped) رکوردها. #812 https://github.com/pallets-eco/flask-sqlalchemy/pull/812

منتشرشده در 2019-09-24

•
رفع خطای AttributeError هنگام استفاده از چندین bind با مدل‌های چندریختی (polymorphic). #651 https://github.com/pallets-eco/flask-sqlalchemy/pull/651

منتشرشده در 2019-04-24

منتشرشده در 2017-10-11

•
عدم پنهان‌سازی جدول والد برای مدل‌های وراثت تک‌جدولی (single-table inheritance). #561 https://github.com/pallets-eco/flask-sqlalchemy/pull/561

منتشرشده در 2017-10-05

منتشرشده در 2017-09-28

  • رفع چندین باگ در تولید خودکار __tablename__. نام‌ها برای مدل‌هایی که یک کلید اصلی تعریف می‌کنند تولید خواهد شد، اما برای زیرکلاس‌های وراثت تک‌جدولی (single-table inheritance) خیر. نام‌ها ویژگی declared_attr را رونویسی نخواهند کرد. PrimaryKeyConstraint شناسایی می‌شود. #541 https://github.com/pallets-eco/flask-sqlalchemy/pull/541
  • ارسال یک declarative_base() موجود به عنوان model_class به SQLAlchemy.__init__ باعث می‌شود از آن به عنوان کلاس پایه به جای ساخت کلاس جدید استفاده شود. این امر اجازه سفارشی‌سازی metaclass مورد استفاده برای ساخت کلاس پایه را می‌دهد. #546 https://github.com/pallets-eco/flask-sqlalchemy/issues/546
  • بخش‌های درونی و مستندنیافته‌ی DeclarativeMeta که این افزونه برای bindها و تولید نام جدول استفاده می‌کرد، به صورت mixin بازطراحی شدند. مستنداتی درباره چگونگی ایجاد یک metaclass سفارشی که نام جدول را تولید نمی‌کند، اضافه شد. #546 https://github.com/pallets-eco/flask-sqlalchemy/issues/546
  • کدهای مدل و metaclass به ماژول جدید models منتقل شدند. نام _BoundDeclarativeMeta به DefaultMeta تغییر یافت؛ نام قبلی در نسخه 3.0 حذف خواهد شد. #546 https://github.com/pallets-eco/flask-sqlalchemy/issues/546
  • مدل‌ها یک repr پیش‌فرض دارند که نام مدل و کلید اصلی را نشان می‌دهد. #530 https://github.com/pallets-eco/flask-sqlalchemy/pull/530
  • رفع باگی که در آن استفاده از init_app باعث می‌شد متصل‌کننده‌ها همیشه به جای برنامه‌ای که برای آن ساخته شده‌اند از current_app استفاده کنند. این امر هنگام ثبت چندین برنامه در افزونه مشکلاتی ایجاد می‌کرد. #547 https://github.com/pallets-eco/flask-sqlalchemy/pull/547

منتشرشده در 2017-02-27، با نام رمز Dubnium

  • نام‌های جدول در موارد بیشتری، از جمله ارث‌بری از mixinها و مدل‌های انتزاعی، به‌طور خودکار تولید می‌شوند.
  • امکان استفاده از یک شیء سفارشی MetaData فراهم شد.
  • افزودن پشتیبانی از پارامتر binds برای session.

منتشرشده در 2014-08-29، با نام رمز Bohrium

  • تغییر نحوهٔ اشتراک در سیگنال‌های توکار به منظور نادیده گرفتن نشست‌های غیر Flask-SQLAlchemy. این تغییر همچنین خطای مشخصه (attribute error) مبنی بر عدم وجود تغییرات مدل را رفع می‌کند.
  • افزودن روشی برای کنترل نحوهٔ ردیابی سیگنال‌های تغییرات مدل.
  • تبدیل SignallingSession به یک رابط عمومی و افزودن یک هوک (hook) برای سفارشی‌سازی ایجاد نشست.
  • اگر پارامتر bind به نشست سیگنال‌دهنده داده شود، دیگر خطایی مبنی بر ارسال دوبارهٔ یک پارامتر ایجاد نخواهد کرد.
  • افزودن پشتیبانی کاربردی از بازتاب جدول (table reflection).
  • فعال‌سازی پیش‌فرض autoflush.
  • مضر در نظر گرفتن SQLALCHEMY_COMMIT_ON_TEARDOWN و حذف آن از مستندات.

منتشرشده در 2013-07-20، با نام رمز Aurum

  • پشتیبانی از Python 3.3 اضافه شد.
  • سازگاری با Python 2.5 کنار گذاشته شد.
  • رفع اشکالات گوناگون.
  • تغییر قالب نسخه‌گذاری برای انتشار نسخه‌های اصلی (major) در هر به‌روزرسانی از این پس.

  • قالب توزیع جدید (flask_sqlalchemy).
  • افزودن پشتیبانی از ویژگی‌های خاص Flask 0.9.

•
افزودن پشتیبانی نشست (session) برای چندین پایگاه داده.

•
محاسبهٔ مسیرهای نسبی sqlite به‌صورت نسبی نسبت به ریشهٔ برنامه.

•
رفع مشکلی که در آن Flask-SQLAlchemy متصل‌کننده‌های (binds) صحیح را انتخاب نمی‌کرد.

  • پشتیبانی از چندین پایگاه داده اضافه شد.
  • در دسترس قرار دادن BaseQuery به‌صورت db.Query.
  • تنظیم مقدار پیش‌فرض query_class برای db.relation، db.relationship و db.dynamic_loader روی BaseQuery.
  • بهبود سازگاری با Flask 0.7.
•
رفع باگ ایجاد شده در نسخه 0.10 مربوط به سازنده‌های جایگزین جدول.

  • افزودن پشتیبانی از سیگنال‌ها.
  • نام‌های جدول اکنون به‌طور خودکار از نام کلاس تنظیم می‌شوند، مگر اینکه بازنویسی شوند.
  • اکنون Model.query همیشه برای برنامه‌هایی که مستقیماً به سازندهٔ SQLAlchemy ارسال می‌شوند کار می‌کند. علاوه بر این، این ویژگی اکنون به‌جای None بودن، خطای RuntimeError صادر می‌کند.
  • افزودن گزینه‌های نشست (session) به سازنده.
  • رفع اشکال __repr__ معیوب.
  • اکنون db.Table یک تابع کارخانه‌ای است که اشیاء جدول را ایجاد می‌کند. این ویژگی امکان حذف متادیتا را ممکن می‌سازد.

•
اعمال تغییرات برای قبولی در فرآیند تأیید افزونهٔ Flask.

  • افزودن چند کلید پیکربندی برای ایجاد اتصالات.
  • فعال‌سازی خودکار بازیافت اتصال (connection recycling) برای اتصالات MySQL.
  • افزودن پشتیبانی از حالت آزمایشی Flask.

•
نخستین انتشار عمومی

Pallets

2010 Pallets

December 15, 2025 3.1.x