Cluster ERP'nin her iş tablosu migrations/ içindeki tek bir Alembic geçmişinden gelir. Aynı geçmiş yeni bir kiracı veritabanını kurar, var olan birini yükseltir ve sürekli tümleştirmede denetlenir. Bu sayfa onu kimin koştuğunu, paralel işçilerin nasıl ayrı tutulduğunu ve şemanın hangi parçalarının o geçmişte olmadığını açıklar. Onu çok sayıda kiracı için koşan operatör komutları kiracı yaşam döngüsü sayfasındadır.
Kısaca¶
migrations/versions/218 revizyon dosyası içerir; o klasörün*.pydosyaları olarak sayıldı (ls migrations/versions/*.py).alembic.iniveritabanı adresi taşımaz;migrations/env.pyadresiSettingsüzerinden veya çağıranın verdiği bir adresten alır (migrations/env.py:42-73).- Bütün koşular, yükseltme süresince bir PostgreSQL danışma kilidi tutan
upgrade_database_to_headüzerinden geçer (src/cluster_erp/core/tenancy.py:665-720). - Çok kiracılı bir işçi varsayılan veritabanını açılışta göç ettirir; tek kiracılı bir düğümü
install.shyeniden başlatmadan önce göç ettirir (src/cluster_erp/server/app.py:99-113,deploy/install.sh:221-226). - Sürekli tümleştirme bütün geçmişi boş bir PostgreSQL 16 veritabanına uygular ve tam olarak bir baş ister (
.github/workflows/ci.yml:110-117).
Nasıl çalışır¶
Adres nereden gelir¶
migrations/env.py hedef veritabanına şu sırayla karar verir (migrations/env.py:56-73):
- Bir programın
cfg.attributes["explicit_url"]içine koyduğu adres.upgrade_database_to_headbunu her zaman koyar; böylece kiracı hazırlama ve filo çalıştırıcısı amaçlanan veritabanına ulaşır (src/cluster_erp/core/tenancy.py:687-692). - Yoksa
CLUSTER_ERP_DB_*değişkenlerinden kurulanSettings().database_url_sync. Settingskurulamazsa koşu, bir veritabanı tahmin etmek yerine hatayla durur.
alembic.ini günlük bölümü yalnız henüz hiçbir günlük yapılandırılmamışsa uygulanır; böylece süreç içi bir koşu uygulama günlüğünü susturmaz (migrations/env.py:32-40). env.py, target_metadata değerini doldurmak için her modülün üst düzey models.py dosyasını içe aktarır (migrations/env.py:76-86).
Geçmişi kim koşar¶
Diyagram geçmişin her çağıranını gösterir.
flowchart LR ci["CI: alembic upgrade head"] --> alembic["Alembic command.upgrade"] inst["install.sh tek kiracılı"] --> alembic boot["işçi lifespan çok kiracılı"] --> uh["upgrade_database_to_head"] prov["provision_tenant"] --> uh upg["upgrade_tenants"] --> uh uh --> lock["migration_lock"] lock --> alembic
Düz yazıyla:
- Sürekli tümleştirme boş bir veritabanında
python -m alembic upgrade headkoşar (.github/workflows/ci.yml:113). - Tek kiracılı bir düğümde
install.shyedek alır vealembic upgrade headkoşar (deploy/install.sh:221-226). - Çok kiracılı kipte her işçi gerekirse varsayılan veritabanını oluşturur ve açılışta
upgrade_database_to_headçağırır (src/cluster_erp/server/app.py:110-113). provision_tenantgeçmişi yeni bir kiracı veritabanında yeniden oynatır (src/cluster_erp/server/provision_tenant.py:132-137).upgrade_tenants, revizyonu baştan farklı olan her kiracıyı yükseltir (src/cluster_erp/server/upgrade_tenants.py:83-100).
Açılış göç kilidi¶
upgrade_database_to_head, command.upgrade(cfg, "head") çağrısını migration_lock ile sarar. Kilit, hedef veritabanında alınan ve sonda bırakılan, sabit MIGRATION_LOCK_KEY anahtarlı pg_advisory_lock kilididir (src/cluster_erp/core/tenancy.py:693-720). İkinci bir işçi ilki bitene kadar bekler ve sonra başın zaten uygulanmış olduğunu görür (src/cluster_erp/core/tenancy.py:693-699). tests/test_boot_migration_lock.py testi ikinci tutucunun ilkini beklediğini denetler.
Neden böyle kurulmuştur¶
- Tek geçmiş, hazırlanan bir kiracıyı göç ettirilmiş bir dağıtımla aynı tutar (
src/cluster_erp/core/tenancy.py:666-672). - Veritabanı adresi
alembic.iniiçinde saklanmaz, çünkü "a tracked credential is a liability" (migrations/env.py:60-63). - Kilit, iki işçinin bir kez aynı anda yeni bir revizyonu oynatması ve birinin açılamaması üzerine vardır (
src/cluster_erp/core/tenancy.py:693-698). - Projenin yazılı mühendislik kuralları bir modülün
create_allçağırmadığını, şemanın Alembic göçleriyle geldiğini söyler.
Kurallar ve sınırlar¶
- Yayımlanmış göçler donmuştur:
pyproject.tomlonlara "frozen historical records (never edited after they ship)" der ve onları yalnız satır uzunluğu kuralından muaf tutar (pyproject.toml:134-136).tests/içindemigrations/versionsaranarak bu kuralı uygulayan bir test bulunmadı. alembic checkhenüz bir kapı değildir. İş akışı açıklaması,env.pyyalnız üst düzey model dosyalarını içe aktardığı için karşılaştırmanın yanlış farklar bildirdiğini söyler (.github/workflows/ci.yml:118-123).- Bir göç revizyonu yalnız hedef baştan gerideyse uygulanır;
upgrade_tenants --dry-runher veritabanının güncel ve baş revizyonunu değişiklik yapmadan listeler (src/cluster_erp/server/upgrade_tenants.py:84-97).
Diğer parçalarla etkileşim¶
- Kontrol düzlemi veritabanının Alembic geçmişi yoktur.
TenantRegistry.ensure_schematablolarınıcreate_allile oluşturur ve sonradan gelen sütunları eş güçlüALTER TABLE ... IF NOT EXISTSifadeleriyle ekler (src/cluster_erp/core/tenancy.py:387-410). - Her açılışta bir tarama,
deleted_atsütunu olupdeactivation_reasonvedeactivation_notesütunları olmayan her tabloya bu sütunları kendi işlem danışma kilidi altında ekler (src/cluster_erp/server/app.py:1111-1166). Bkz. yumuşak silme ve devre dışı bırakma. - Bir sürüm şema adımından sonra tohumları da yeniler; bkz. kiracı yaşam döngüsü.
Sınırlar ve açık noktalar¶
- Bir sürümün geri alınması: Koddan belirlenemedi.
src,deployvescriptsiçinde arandı;command.downgradeçağrısı bulunmadı. install.shgöçten önce tek kiracılı ve çok kiracılı kipte yedek alır (deploy/install.sh:214-226). Bkz. yedekler ve geri yükleme.
Tanıtılan terimler¶
| Terim | Kod tanımlayıcısı | Tanım | Türkçe terim | Kaynak |
|---|---|---|---|---|
| baş revizyon | get_current_head |
Alembic geçmişinin en yeni revizyonu. | baş revizyon | src/cluster_erp/server/upgrade_tenants.py:42-44 |
| açık adres | explicit_url |
Bir programın Alembic'e verdiği veritabanı adresi; ayarlara üstün gelir. | açık adres | migrations/env.py:56-58 |
İlgili sayfalar¶
92f8051 numaralı commit ile 2026-11-13 tarihinde doğrulandı.