1pub const POSTGRES_MIGRATIONS: &[&str] = &[
5 r#"
7-- 创建模型表
8CREATE TABLE IF NOT EXISTS models (
9 id UUID PRIMARY KEY,
10 name VARCHAR(255) NOT NULL UNIQUE,
11 display_name VARCHAR(255) NOT NULL,
12 description TEXT,
13 version VARCHAR(100) NOT NULL,
14 model_type VARCHAR(50) NOT NULL,
15 size_category VARCHAR(50) NOT NULL,
16 file_size BIGINT NOT NULL,
17 provider VARCHAR(255) NOT NULL,
18 license VARCHAR(255),
19 tags JSONB NOT NULL DEFAULT '[]',
20 languages JSONB NOT NULL DEFAULT '[]',
21 created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
22 updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
23 file_path VARCHAR(500),
24 checksum VARCHAR(255),
25 download_url TEXT,
26 config JSONB NOT NULL DEFAULT '{}',
27 rating REAL,
28 download_count BIGINT NOT NULL DEFAULT 0,
29 is_official BOOLEAN NOT NULL DEFAULT false
30);
31
32-- 创建已安装模型表
33CREATE TABLE IF NOT EXISTS installed_models (
34 id UUID PRIMARY KEY,
35 model_id UUID NOT NULL REFERENCES models(id) ON DELETE CASCADE,
36 install_path VARCHAR(500) NOT NULL,
37 installed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
38 status VARCHAR(50) NOT NULL,
39 port INTEGER,
40 process_id INTEGER,
41 last_used TIMESTAMPTZ,
42 usage_count BIGINT NOT NULL DEFAULT 0,
43 UNIQUE(model_id)
44);
45
46-- 创建可用模型表
47CREATE TABLE IF NOT EXISTS available_models (
48 id UUID PRIMARY KEY,
49 model_id UUID NOT NULL REFERENCES models(id) ON DELETE CASCADE,
50 is_installed BOOLEAN NOT NULL DEFAULT false,
51 published_at TIMESTAMPTZ NOT NULL,
52 last_updated TIMESTAMPTZ NOT NULL,
53 system_requirements JSONB NOT NULL,
54 UNIQUE(model_id)
55);
56
57-- 创建运行时配置表
58CREATE TABLE IF NOT EXISTS runtime_configs (
59 id UUID PRIMARY KEY,
60 name VARCHAR(255) NOT NULL,
61 max_context_length INTEGER,
62 temperature REAL,
63 top_p REAL,
64 top_k INTEGER,
65 max_tokens INTEGER,
66 stop_sequences JSONB NOT NULL DEFAULT '[]',
67 batch_size INTEGER,
68 max_concurrent_requests INTEGER,
69 gpu_device_ids JSONB NOT NULL DEFAULT '[]',
70 memory_limit_mb BIGINT,
71 enable_streaming BOOLEAN NOT NULL DEFAULT true,
72 custom_params JSONB NOT NULL DEFAULT '{}',
73 created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
74 updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
75);
76
77-- 创建模型运行时表
78CREATE TABLE IF NOT EXISTS model_runtimes (
79 id UUID PRIMARY KEY,
80 model_id UUID NOT NULL REFERENCES models(id) ON DELETE CASCADE,
81 runtime_config_id UUID NOT NULL REFERENCES runtime_configs(id) ON DELETE CASCADE,
82 name VARCHAR(255) NOT NULL,
83 port INTEGER NOT NULL,
84 process_id INTEGER,
85 started_at TIMESTAMPTZ,
86 stopped_at TIMESTAMPTZ,
87 status VARCHAR(50) NOT NULL,
88 health_endpoint VARCHAR(255) NOT NULL,
89 api_endpoint VARCHAR(255) NOT NULL,
90 log_file VARCHAR(500),
91 environment JSONB NOT NULL DEFAULT '{}',
92 created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
93 updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
94 UNIQUE(model_id, port)
95);
96
97-- 创建运行时指标表
98CREATE TABLE IF NOT EXISTS runtime_metrics (
99 id UUID PRIMARY KEY,
100 runtime_id UUID NOT NULL REFERENCES model_runtimes(id) ON DELETE CASCADE,
101 timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
102 cpu_usage_percent REAL NOT NULL,
103 memory_usage_mb BIGINT NOT NULL,
104 gpu_usage_percent REAL,
105 gpu_memory_usage_mb BIGINT,
106 active_connections INTEGER NOT NULL,
107 total_requests BIGINT NOT NULL,
108 successful_requests BIGINT NOT NULL,
109 failed_requests BIGINT NOT NULL,
110 avg_response_time_ms REAL NOT NULL,
111 throughput_rps REAL NOT NULL,
112 queue_length INTEGER NOT NULL
113);
114
115-- 创建运行时事件表
116CREATE TABLE IF NOT EXISTS runtime_events (
117 id UUID PRIMARY KEY,
118 runtime_id UUID NOT NULL REFERENCES model_runtimes(id) ON DELETE CASCADE,
119 event_type VARCHAR(50) NOT NULL,
120 timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
121 message TEXT NOT NULL,
122 details JSONB,
123 severity VARCHAR(20) NOT NULL
124);
125
126-- 创建索引
127CREATE INDEX IF NOT EXISTS idx_models_name ON models(name);
128CREATE INDEX IF NOT EXISTS idx_models_provider ON models(provider);
129CREATE INDEX IF NOT EXISTS idx_models_model_type ON models(model_type);
130CREATE INDEX IF NOT EXISTS idx_models_created_at ON models(created_at);
131CREATE INDEX IF NOT EXISTS idx_installed_models_model_id ON installed_models(model_id);
132CREATE INDEX IF NOT EXISTS idx_installed_models_status ON installed_models(status);
133CREATE INDEX IF NOT EXISTS idx_available_models_model_id ON available_models(model_id);
134CREATE INDEX IF NOT EXISTS idx_runtime_metrics_runtime_id ON runtime_metrics(runtime_id);
135CREATE INDEX IF NOT EXISTS idx_runtime_metrics_timestamp ON runtime_metrics(timestamp);
136CREATE INDEX IF NOT EXISTS idx_runtime_events_runtime_id ON runtime_events(runtime_id);
137CREATE INDEX IF NOT EXISTS idx_runtime_events_timestamp ON runtime_events(timestamp);
138"#,
139
140 r#"
142-- 创建模型仓库表
143CREATE TABLE IF NOT EXISTS model_repositories (
144 id UUID PRIMARY KEY,
145 name VARCHAR(255) NOT NULL UNIQUE,
146 url TEXT NOT NULL,
147 repo_type VARCHAR(50) NOT NULL,
148 enabled BOOLEAN NOT NULL DEFAULT true,
149 auth_config JSONB,
150 last_sync TIMESTAMPTZ,
151 sync_status VARCHAR(50) NOT NULL DEFAULT 'never',
152 description TEXT,
153 tags JSONB NOT NULL DEFAULT '[]',
154 priority INTEGER NOT NULL DEFAULT 100,
155 created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
156 updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
157);
158
159-- 创建仓库索引表
160CREATE TABLE IF NOT EXISTS repository_indexes (
161 id UUID PRIMARY KEY,
162 repository_id UUID NOT NULL REFERENCES model_repositories(id) ON DELETE CASCADE,
163 version VARCHAR(100) NOT NULL,
164 updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
165 checksum VARCHAR(255),
166 metadata JSONB NOT NULL DEFAULT '{}',
167 UNIQUE(repository_id)
168);
169
170-- 创建仓库模型表
171CREATE TABLE IF NOT EXISTS repository_models (
172 id UUID PRIMARY KEY,
173 repository_id UUID NOT NULL REFERENCES model_repositories(id) ON DELETE CASCADE,
174 model_id UUID NOT NULL REFERENCES models(id) ON DELETE CASCADE,
175 repo_model_id VARCHAR(255) NOT NULL,
176 repo_path VARCHAR(500) NOT NULL,
177 download_urls JSONB NOT NULL DEFAULT '[]',
178 files JSONB NOT NULL DEFAULT '[]',
179 dependencies JSONB NOT NULL DEFAULT '[]',
180 installation_notes TEXT,
181 usage_examples JSONB NOT NULL DEFAULT '[]',
182 license_text TEXT,
183 model_card TEXT,
184 created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
185 updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
186 UNIQUE(repository_id, repo_model_id)
187);
188
189-- 创建同步结果表
190CREATE TABLE IF NOT EXISTS sync_results (
191 id UUID PRIMARY KEY,
192 repository_id UUID NOT NULL REFERENCES model_repositories(id) ON DELETE CASCADE,
193 started_at TIMESTAMPTZ NOT NULL,
194 completed_at TIMESTAMPTZ,
195 status VARCHAR(50) NOT NULL,
196 models_added INTEGER NOT NULL DEFAULT 0,
197 models_updated INTEGER NOT NULL DEFAULT 0,
198 models_removed INTEGER NOT NULL DEFAULT 0,
199 error_message TEXT,
200 log_entries JSONB NOT NULL DEFAULT '[]'
201);
202
203-- 创建索引
204CREATE INDEX IF NOT EXISTS idx_repository_models_repository_id ON repository_models(repository_id);
205CREATE INDEX IF NOT EXISTS idx_repository_models_model_id ON repository_models(model_id);
206CREATE INDEX IF NOT EXISTS idx_sync_results_repository_id ON sync_results(repository_id);
207CREATE INDEX IF NOT EXISTS idx_sync_results_started_at ON sync_results(started_at);
208"#,
209
210 r#"
212-- 创建全局配置表
213CREATE TABLE IF NOT EXISTS global_configs (
214 id UUID PRIMARY KEY,
215 version VARCHAR(100) NOT NULL,
216 config_data JSONB NOT NULL,
217 created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
218 updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
219);
220
221-- 创建系统指标表
222CREATE TABLE IF NOT EXISTS system_metrics (
223 id UUID PRIMARY KEY,
224 timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
225 cpu_usage_percent REAL NOT NULL,
226 cpu_cores INTEGER NOT NULL,
227 memory_total_bytes BIGINT NOT NULL,
228 memory_used_bytes BIGINT NOT NULL,
229 memory_usage_percent REAL NOT NULL,
230 disk_total_bytes BIGINT NOT NULL,
231 disk_used_bytes BIGINT NOT NULL,
232 disk_usage_percent REAL NOT NULL,
233 network_rx_bytes_per_sec BIGINT NOT NULL,
234 network_tx_bytes_per_sec BIGINT NOT NULL,
235 gpu_usage_percent REAL,
236 gpu_memory_usage_mb BIGINT,
237 load_1m REAL NOT NULL,
238 load_5m REAL NOT NULL,
239 load_15m REAL NOT NULL
240);
241
242-- 创建应用指标表
243CREATE TABLE IF NOT EXISTS application_metrics (
244 id UUID PRIMARY KEY,
245 timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
246 uptime_seconds BIGINT NOT NULL,
247 total_requests BIGINT NOT NULL,
248 successful_requests BIGINT NOT NULL,
249 failed_requests BIGINT NOT NULL,
250 active_connections INTEGER NOT NULL,
251 avg_response_time_ms REAL NOT NULL,
252 p95_response_time_ms REAL NOT NULL,
253 p99_response_time_ms REAL NOT NULL,
254 current_qps REAL NOT NULL,
255 peak_qps REAL NOT NULL,
256 error_rate_percent REAL NOT NULL,
257 health_status VARCHAR(20) NOT NULL
258);
259
260-- 创建模型指标表
261CREATE TABLE IF NOT EXISTS model_metrics (
262 id UUID PRIMARY KEY,
263 model_id UUID NOT NULL REFERENCES models(id) ON DELETE CASCADE,
264 runtime_id UUID REFERENCES model_runtimes(id) ON DELETE SET NULL,
265 timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
266 status VARCHAR(50) NOT NULL,
267 total_requests BIGINT NOT NULL,
268 successful_requests BIGINT NOT NULL,
269 failed_requests BIGINT NOT NULL,
270 avg_inference_time_ms REAL NOT NULL,
271 tokens_per_second REAL NOT NULL,
272 memory_usage_bytes BIGINT NOT NULL,
273 gpu_memory_usage_bytes BIGINT,
274 cpu_usage_percent REAL NOT NULL,
275 gpu_usage_percent REAL,
276 queue_length INTEGER NOT NULL,
277 last_request_time TIMESTAMPTZ
278);
279
280-- 创建告警事件表
281CREATE TABLE IF NOT EXISTS alert_events (
282 id UUID PRIMARY KEY,
283 alert_type VARCHAR(100) NOT NULL,
284 severity VARCHAR(20) NOT NULL,
285 title VARCHAR(255) NOT NULL,
286 description TEXT NOT NULL,
287 triggered_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
288 resolved_at TIMESTAMPTZ,
289 status VARCHAR(20) NOT NULL DEFAULT 'triggered',
290 resource_type VARCHAR(100) NOT NULL,
291 resource_id VARCHAR(255) NOT NULL,
292 resource_name VARCHAR(255) NOT NULL,
293 value REAL NOT NULL,
294 threshold REAL NOT NULL,
295 labels JSONB NOT NULL DEFAULT '{}',
296 metadata JSONB NOT NULL DEFAULT '{}'
297);
298
299-- 创建索引
300CREATE INDEX IF NOT EXISTS idx_system_metrics_timestamp ON system_metrics(timestamp);
301CREATE INDEX IF NOT EXISTS idx_application_metrics_timestamp ON application_metrics(timestamp);
302CREATE INDEX IF NOT EXISTS idx_model_metrics_model_id ON model_metrics(model_id);
303CREATE INDEX IF NOT EXISTS idx_model_metrics_timestamp ON model_metrics(timestamp);
304CREATE INDEX IF NOT EXISTS idx_alert_events_triggered_at ON alert_events(triggered_at);
305CREATE INDEX IF NOT EXISTS idx_alert_events_status ON alert_events(status);
306CREATE INDEX IF NOT EXISTS idx_alert_events_severity ON alert_events(severity);
307"#,
308
309 r#"
311-- 创建用户会话表
312CREATE TABLE IF NOT EXISTS user_sessions (
313 id UUID PRIMARY KEY,
314 user_id VARCHAR(255) NOT NULL,
315 session_token VARCHAR(255) NOT NULL UNIQUE,
316 created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
317 expires_at TIMESTAMPTZ NOT NULL,
318 last_accessed TIMESTAMPTZ NOT NULL DEFAULT NOW(),
319 ip_address INET NOT NULL,
320 user_agent TEXT,
321 is_active BOOLEAN NOT NULL DEFAULT true
322);
323
324-- 创建API使用统计表
325CREATE TABLE IF NOT EXISTS api_usage (
326 id UUID PRIMARY KEY,
327 api_key_id UUID,
328 endpoint VARCHAR(255) NOT NULL,
329 method VARCHAR(10) NOT NULL,
330 timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
331 response_time_ms INTEGER NOT NULL,
332 status_code INTEGER NOT NULL,
333 request_size_bytes BIGINT NOT NULL,
334 response_size_bytes BIGINT NOT NULL,
335 ip_address INET NOT NULL,
336 user_agent TEXT
337);
338
339-- 创建任务队列表
340CREATE TABLE IF NOT EXISTS tasks (
341 id UUID PRIMARY KEY,
342 task_type VARCHAR(100) NOT NULL,
343 payload JSONB NOT NULL,
344 status VARCHAR(20) NOT NULL DEFAULT 'pending',
345 priority INTEGER NOT NULL DEFAULT 0,
346 created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
347 started_at TIMESTAMPTZ,
348 completed_at TIMESTAMPTZ,
349 error_message TEXT,
350 retry_count INTEGER NOT NULL DEFAULT 0,
351 max_retries INTEGER NOT NULL DEFAULT 3,
352 scheduled_at TIMESTAMPTZ
353);
354
355-- 创建下载任务表
356CREATE TABLE IF NOT EXISTS download_tasks (
357 id UUID PRIMARY KEY,
358 model_id UUID NOT NULL REFERENCES models(id) ON DELETE CASCADE,
359 url TEXT NOT NULL,
360 file_path VARCHAR(500) NOT NULL,
361 total_size BIGINT NOT NULL,
362 downloaded_size BIGINT NOT NULL DEFAULT 0,
363 status VARCHAR(20) NOT NULL DEFAULT 'pending',
364 progress_percent REAL NOT NULL DEFAULT 0,
365 download_speed_bps BIGINT NOT NULL DEFAULT 0,
366 estimated_time_remaining INTEGER,
367 created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
368 started_at TIMESTAMPTZ,
369 completed_at TIMESTAMPTZ,
370 error_message TEXT
371);
372
373-- 创建索引
374CREATE INDEX IF NOT EXISTS idx_user_sessions_user_id ON user_sessions(user_id);
375CREATE INDEX IF NOT EXISTS idx_user_sessions_session_token ON user_sessions(session_token);
376CREATE INDEX IF NOT EXISTS idx_user_sessions_expires_at ON user_sessions(expires_at);
377CREATE INDEX IF NOT EXISTS idx_api_usage_timestamp ON api_usage(timestamp);
378CREATE INDEX IF NOT EXISTS idx_api_usage_endpoint ON api_usage(endpoint);
379CREATE INDEX IF NOT EXISTS idx_tasks_status ON tasks(status);
380CREATE INDEX IF NOT EXISTS idx_tasks_task_type ON tasks(task_type);
381CREATE INDEX IF NOT EXISTS idx_tasks_created_at ON tasks(created_at);
382CREATE INDEX IF NOT EXISTS idx_download_tasks_model_id ON download_tasks(model_id);
383CREATE INDEX IF NOT EXISTS idx_download_tasks_status ON download_tasks(status);
384"#,
385
386 r#"
388-- 创建自动更新 updated_at 字段的函数
389CREATE OR REPLACE FUNCTION update_updated_at_column()
390RETURNS TRIGGER AS $$
391BEGIN
392 NEW.updated_at = NOW();
393 RETURN NEW;
394END;
395$$ LANGUAGE plpgsql;
396
397-- 为需要的表创建触发器
398CREATE TRIGGER update_models_updated_at BEFORE UPDATE ON models
399 FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
400
401CREATE TRIGGER update_runtime_configs_updated_at BEFORE UPDATE ON runtime_configs
402 FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
403
404CREATE TRIGGER update_model_runtimes_updated_at BEFORE UPDATE ON model_runtimes
405 FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
406
407CREATE TRIGGER update_model_repositories_updated_at BEFORE UPDATE ON model_repositories
408 FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
409
410CREATE TRIGGER update_repository_models_updated_at BEFORE UPDATE ON repository_models
411 FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
412
413CREATE TRIGGER update_global_configs_updated_at BEFORE UPDATE ON global_configs
414 FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
415
416-- 创建清理过期数据的函数
417CREATE OR REPLACE FUNCTION cleanup_old_metrics()
418RETURNS void AS $$
419BEGIN
420 -- 清理30天前的系统指标
421 DELETE FROM system_metrics WHERE timestamp < NOW() - INTERVAL '30 days';
422
423 -- 清理30天前的应用指标
424 DELETE FROM application_metrics WHERE timestamp < NOW() - INTERVAL '30 days';
425
426 -- 清理7天前的运行时指标
427 DELETE FROM runtime_metrics WHERE timestamp < NOW() - INTERVAL '7 days';
428
429 -- 清理90天前的API使用记录
430 DELETE FROM api_usage WHERE timestamp < NOW() - INTERVAL '90 days';
431
432 -- 清理过期的用户会话
433 DELETE FROM user_sessions WHERE expires_at < NOW();
434END;
435$$ LANGUAGE plpgsql;
436
437-- 创建计算模型统计信息的函数
438CREATE OR REPLACE FUNCTION get_model_stats(model_uuid UUID)
439RETURNS JSON AS $$
440DECLARE
441 result JSON;
442BEGIN
443 SELECT json_build_object(
444 'total_requests', COALESCE(SUM(total_requests), 0),
445 'successful_requests', COALESCE(SUM(successful_requests), 0),
446 'failed_requests', COALESCE(SUM(failed_requests), 0),
447 'avg_inference_time_ms', COALESCE(AVG(avg_inference_time_ms), 0),
448 'avg_tokens_per_second', COALESCE(AVG(tokens_per_second), 0),
449 'last_activity', MAX(timestamp)
450 ) INTO result
451 FROM model_metrics
452 WHERE model_id = model_uuid
453 AND timestamp >= NOW() - INTERVAL '24 hours';
454
455 RETURN result;
456END;
457$$ LANGUAGE plpgsql;
458"#,
459];
460
461pub const SQLITE_MIGRATIONS: &[&str] = &[
463 r#"
465-- 创建模型表
466CREATE TABLE IF NOT EXISTS models (
467 id TEXT PRIMARY KEY,
468 name TEXT NOT NULL UNIQUE,
469 display_name TEXT NOT NULL,
470 description TEXT,
471 version TEXT NOT NULL,
472 model_type TEXT NOT NULL,
473 size_category TEXT NOT NULL,
474 file_size INTEGER NOT NULL,
475 provider TEXT NOT NULL,
476 license TEXT,
477 tags TEXT NOT NULL DEFAULT '[]',
478 languages TEXT NOT NULL DEFAULT '[]',
479 created_at TEXT NOT NULL DEFAULT (datetime('now')),
480 updated_at TEXT NOT NULL DEFAULT (datetime('now')),
481 file_path TEXT,
482 checksum TEXT,
483 download_url TEXT,
484 config TEXT NOT NULL DEFAULT '{}',
485 rating REAL,
486 download_count INTEGER NOT NULL DEFAULT 0,
487 is_official INTEGER NOT NULL DEFAULT 0
488);
489
490-- 创建已安装模型表
491CREATE TABLE IF NOT EXISTS installed_models (
492 id TEXT PRIMARY KEY,
493 model_id TEXT NOT NULL,
494 install_path TEXT NOT NULL,
495 installed_at TEXT NOT NULL DEFAULT (datetime('now')),
496 status TEXT NOT NULL,
497 port INTEGER,
498 process_id INTEGER,
499 last_used TEXT,
500 usage_count INTEGER NOT NULL DEFAULT 0,
501 FOREIGN KEY (model_id) REFERENCES models(id) ON DELETE CASCADE,
502 UNIQUE(model_id)
503);
504
505-- 创建可用模型表
506CREATE TABLE IF NOT EXISTS available_models (
507 id TEXT PRIMARY KEY,
508 model_id TEXT NOT NULL,
509 is_installed INTEGER NOT NULL DEFAULT 0,
510 published_at TEXT NOT NULL,
511 last_updated TEXT NOT NULL,
512 system_requirements TEXT NOT NULL,
513 FOREIGN KEY (model_id) REFERENCES models(id) ON DELETE CASCADE,
514 UNIQUE(model_id)
515);
516
517-- 创建运行时配置表
518CREATE TABLE IF NOT EXISTS runtime_configs (
519 id TEXT PRIMARY KEY,
520 name TEXT NOT NULL,
521 max_context_length INTEGER,
522 temperature REAL,
523 top_p REAL,
524 top_k INTEGER,
525 max_tokens INTEGER,
526 stop_sequences TEXT NOT NULL DEFAULT '[]',
527 batch_size INTEGER,
528 max_concurrent_requests INTEGER,
529 gpu_device_ids TEXT NOT NULL DEFAULT '[]',
530 memory_limit_mb INTEGER,
531 enable_streaming INTEGER NOT NULL DEFAULT 1,
532 custom_params TEXT NOT NULL DEFAULT '{}',
533 created_at TEXT NOT NULL DEFAULT (datetime('now')),
534 updated_at TEXT NOT NULL DEFAULT (datetime('now'))
535);
536
537-- 创建模型运行时表
538CREATE TABLE IF NOT EXISTS model_runtimes (
539 id TEXT PRIMARY KEY,
540 model_id TEXT NOT NULL,
541 runtime_config_id TEXT NOT NULL,
542 name TEXT NOT NULL,
543 port INTEGER NOT NULL,
544 process_id INTEGER,
545 started_at TEXT,
546 stopped_at TEXT,
547 status TEXT NOT NULL,
548 health_endpoint TEXT NOT NULL,
549 api_endpoint TEXT NOT NULL,
550 log_file TEXT,
551 environment TEXT NOT NULL DEFAULT '{}',
552 created_at TEXT NOT NULL DEFAULT (datetime('now')),
553 updated_at TEXT NOT NULL DEFAULT (datetime('now')),
554 FOREIGN KEY (model_id) REFERENCES models(id) ON DELETE CASCADE,
555 FOREIGN KEY (runtime_config_id) REFERENCES runtime_configs(id) ON DELETE CASCADE,
556 UNIQUE(model_id, port)
557);
558
559-- 创建运行时指标表
560CREATE TABLE IF NOT EXISTS runtime_metrics (
561 id TEXT PRIMARY KEY,
562 runtime_id TEXT NOT NULL,
563 timestamp TEXT NOT NULL DEFAULT (datetime('now')),
564 cpu_usage_percent REAL NOT NULL,
565 memory_usage_mb INTEGER NOT NULL,
566 gpu_usage_percent REAL,
567 gpu_memory_usage_mb INTEGER,
568 active_connections INTEGER NOT NULL,
569 total_requests INTEGER NOT NULL,
570 successful_requests INTEGER NOT NULL,
571 failed_requests INTEGER NOT NULL,
572 avg_response_time_ms REAL NOT NULL,
573 throughput_rps REAL NOT NULL,
574 queue_length INTEGER NOT NULL,
575 FOREIGN KEY (runtime_id) REFERENCES model_runtimes(id) ON DELETE CASCADE
576);
577
578-- 创建运行时事件表
579CREATE TABLE IF NOT EXISTS runtime_events (
580 id TEXT PRIMARY KEY,
581 runtime_id TEXT NOT NULL,
582 event_type TEXT NOT NULL,
583 timestamp TEXT NOT NULL DEFAULT (datetime('now')),
584 message TEXT NOT NULL,
585 details TEXT,
586 severity TEXT NOT NULL,
587 FOREIGN KEY (runtime_id) REFERENCES model_runtimes(id) ON DELETE CASCADE
588);
589
590-- 创建索引
591CREATE INDEX IF NOT EXISTS idx_models_name ON models(name);
592CREATE INDEX IF NOT EXISTS idx_models_provider ON models(provider);
593CREATE INDEX IF NOT EXISTS idx_models_model_type ON models(model_type);
594CREATE INDEX IF NOT EXISTS idx_models_created_at ON models(created_at);
595CREATE INDEX IF NOT EXISTS idx_installed_models_model_id ON installed_models(model_id);
596CREATE INDEX IF NOT EXISTS idx_installed_models_status ON installed_models(status);
597CREATE INDEX IF NOT EXISTS idx_available_models_model_id ON available_models(model_id);
598CREATE INDEX IF NOT EXISTS idx_runtime_metrics_runtime_id ON runtime_metrics(runtime_id);
599CREATE INDEX IF NOT EXISTS idx_runtime_metrics_timestamp ON runtime_metrics(timestamp);
600CREATE INDEX IF NOT EXISTS idx_runtime_events_runtime_id ON runtime_events(runtime_id);
601CREATE INDEX IF NOT EXISTS idx_runtime_events_timestamp ON runtime_events(timestamp);
602"#,
603
604 ];
606
607pub const MYSQL_MIGRATIONS: &[&str] = &[
609 ];
611
612use sqlx::{Database, Pool};
613use async_trait::async_trait;
614
615#[async_trait]
616pub trait MigrationRunner<DB: Database> {
617 async fn run_migrations(pool: &Pool<DB>) -> Result<(), sqlx::Error>;
618 async fn get_migration_version(pool: &Pool<DB>) -> Result<i32, sqlx::Error>;
619}
620
621#[cfg(feature = "postgres")]
622pub struct PostgresMigrationRunner;
623
624#[cfg(feature = "postgres")]
625#[async_trait]
626impl MigrationRunner<sqlx::Postgres> for PostgresMigrationRunner {
627 async fn run_migrations(pool: &Pool<sqlx::Postgres>) -> Result<(), sqlx::Error> {
628 sqlx::query(r#"
630 CREATE TABLE IF NOT EXISTS _migration_history (
631 id SERIAL PRIMARY KEY,
632 version INTEGER NOT NULL UNIQUE,
633 name VARCHAR(255) NOT NULL,
634 applied_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
635 )
636 "#)
637 .execute(pool)
638 .await?;
639
640 let current_version = Self::get_migration_version(pool).await.unwrap_or(0);
642
643 for (index, migration) in POSTGRES_MIGRATIONS.iter().enumerate() {
645 let version = (index + 1) as i32;
646 if version > current_version {
647 sqlx::query(migration).execute(pool).await?;
649
650 sqlx::query(r#"
652 INSERT INTO _migration_history (version, name)
653 VALUES ($1, $2)
654 "#)
655 .bind(version)
656 .bind(format!("migration_{:03}", version))
657 .execute(pool)
658 .await?;
659
660 println!("Applied migration version {}", version);
661 }
662 }
663
664 Ok(())
665 }
666
667 async fn get_migration_version(pool: &Pool<sqlx::Postgres>) -> Result<i32, sqlx::Error> {
668 let row: Option<(i32,)> = sqlx::query_as(
669 "SELECT MAX(version) FROM _migration_history"
670 )
671 .fetch_optional(pool)
672 .await?;
673
674 Ok(row.map(|(v,)| v).unwrap_or(0))
675 }
676}
677
678#[cfg(feature = "sqlite")]
679pub struct SqliteMigrationRunner;
680
681#[cfg(feature = "sqlite")]
682#[async_trait]
683impl MigrationRunner<sqlx::Sqlite> for SqliteMigrationRunner {
684 async fn run_migrations(pool: &Pool<sqlx::Sqlite>) -> Result<(), sqlx::Error> {
685 sqlx::query(r#"
687 CREATE TABLE IF NOT EXISTS _migration_history (
688 id INTEGER PRIMARY KEY AUTOINCREMENT,
689 version INTEGER NOT NULL UNIQUE,
690 name TEXT NOT NULL,
691 applied_at TEXT NOT NULL DEFAULT (datetime('now'))
692 )
693 "#)
694 .execute(pool)
695 .await?;
696
697 let current_version = Self::get_migration_version(pool).await.unwrap_or(0);
699
700 for (index, migration) in SQLITE_MIGRATIONS.iter().enumerate() {
702 let version = (index + 1) as i32;
703 if version > current_version {
704 sqlx::query(migration).execute(pool).await?;
706
707 sqlx::query(r#"
709 INSERT INTO _migration_history (version, name)
710 VALUES (?1, ?2)
711 "#)
712 .bind(version)
713 .bind(format!("migration_{:03}", version))
714 .execute(pool)
715 .await?;
716
717 println!("Applied migration version {}", version);
718 }
719 }
720
721 Ok(())
722 }
723
724 async fn get_migration_version(pool: &Pool<sqlx::Sqlite>) -> Result<i32, sqlx::Error> {
725 let row: Option<(Option<i32>,)> = sqlx::query_as(
726 "SELECT MAX(version) FROM _migration_history"
727 )
728 .fetch_optional(pool)
729 .await?;
730
731 Ok(row.and_then(|(v,)| v).unwrap_or(0))
732 }
733}