ترحيلات قواعد البيانات في Kotlin: كيفية إدارة المخطط بدون ألم
\nعند التطوير باستخدام Kotlin، خاصة مع JVM، عاجلاً أم آجلاً تظهر مهمة مزامنة هيكل قاعدة البيانات بين المطورين والخوادم الاختبارية والإنتاجية. يؤدي تنفيذ نصوص SQL يدويًا إلى عدم التزامن والأخطاء. الحل هو ترحيلات قواعد البيانات. وهي طريقة آلية لإدارة إصدارات تغييرات المخطط: إنشاء الجداول، إضافة الأعمدة، الفهارس والمحفزات.
\nفي هذه المقالة، سنستعرض ثلاث أدوات شائعة لـ Kotlin: Flyway، Liquibase والآلية المدمجة Exposed. ستتعلم كيفية دمجها في المشروع، كتابة الترحيلات وتجنب المشكلات النمطية.
\n\nFlyway: البساطة وإدارة الإصدارات
\nFlyway هي الأداة الأكثر شيوعًا للترحيلات في نظام JVM البيئي. تدعم Kotlin وJava وGroovy. مبدأ العمل: تكتب نصوص SQL (أو فئات Java/Kotlin)، ويتتبع Flyway أي منها تم تطبيقه باستخدام جدول flyway_schema_history.
الإضافة في Gradle (Kotlin DSL):
\ndependencies {\n implementation("org.flywaydb:flyway-core:9.22.3")\n // لـ PostgreSQL\n implementation("org.flywaydb:flyway-database-postgresql:9.22.3")\n}\nمثال لترحيل V1__create_users.sql:
CREATE TABLE users (\n id SERIAL PRIMARY KEY,\n username VARCHAR(50) NOT NULL UNIQUE,\n email VARCHAR(100) NOT NULL,\n created_at TIMESTAMP DEFAULT NOW()\n);\n\nCREATE INDEX idx_users_email ON users(email);\nالتشغيل من كود Kotlin:
\nimport org.flywaydb.core.Flyway\n\nfun main() {\n val flyway = Flyway.configure()\n .dataSource("jdbc:postgresql://localhost:5432/mydb", "user", "pass")\n .load()\n flyway.migrate()\n}\nالمزايا:
\n- \n
- إعدادات ضئيلة \n
- دعم التراجع (undo) في الإصدار المدفوع \n
- يعمل مع أي SQL \n
العيوب:
\n- \n
- لا يوجد تحقق مدمج من المخطط \n
- صعوبة إدارة التفرعات \n
Liquibase: المرونة والتصريحية
\nLiquibase تقدم نهجين: يمكن وصف التغييرات في XML أو YAML أو JSON أو مباشرة في SQL. لمشاريع Kotlin، صيغة YAML مناسبة - فهي قابلة للقراءة وسهلة إدارة الإصدارات.
\nالإضافة في Gradle:
\ndependencies {\n implementation("org.liquibase:liquibase-core:4.24.0")\n}\nمثال لملف changelog db.changelog-master.yaml:
databaseChangeLog:\n - changeSet:\n id: 1\n author: developer\n changes:\n - createTable:\n tableName: users\n columns:\n - column:\n name: id\n type: BIGINT\n autoIncrement: true\n constraints:\n primaryKey: true\n - column:\n name: username\n type: VARCHAR(50)\n constraints:\n nullable: false\n unique: true\n - column:\n name: email\n type: VARCHAR(100)\n - createIndex:\n indexName: idx_users_email\n tableName: users\n columns:\n - column:\n name: email\nالتشغيل من Kotlin:
\nimport liquibase.Liquibase\nimport liquibase.database.jvm.JdbcConnection\nimport liquibase.resource.ClassLoaderResourceAccessor\nimport java.sql.DriverManager\n\nfun runMigrations() {\n val connection = DriverManager.getConnection(\n "jdbc:postgresql://localhost:5432/mydb", "user", "pass"\n )\n val database = DatabaseFactory.getInstance()\n .findCorrectDatabaseImplementation(JdbcConnection(connection))\n val liquibase = Liquibase("db.changelog-mas