Initial commit of akmon project

This commit is contained in:
2026-01-20 08:04:15 +08:00
commit 77a2bab985
1309 changed files with 343305 additions and 0 deletions

191
MISSING_COLUMN_FIX.md Normal file
View File

@@ -0,0 +1,191 @@
# 数据库列不存在错误修复说明
## 问题描述
在执行 `video_system_database.sql` 时,遇到了 `ERROR: 42703: column c.excerpt does not exist` 错误。这表明视图定义中引用了 `ak_contents` 表中不存在的列。
## 根本原因
视图定义假设了 `ak_contents` 表具有某些标准的 CMS 列(如 `title`, `content`, `excerpt`, `slug`, `featured_image`, `status`, `published_at`, `created_at`, `updated_at`),但实际的表结构可能不同。
## 修复方案
### 1. 简化视图定义
修改了所有视图,只使用我们确定存在的列:
```sql
-- 修复前:引用可能不存在的列
CREATE VIEW vw_media_content_detail AS
SELECT
c.id,
c.title, -- 可能不存在
c.content, -- 可能不存在
c.excerpt, -- 可能不存在
c.slug, -- 可能不存在
...
-- 修复后:只使用确定存在的列
CREATE OR REPLACE VIEW vw_media_content_detail AS
SELECT
c.id, -- 主键,肯定存在
c.content_type, -- 我们添加的列
c.video_url, -- 我们添加的列
c.audio_url, -- 我们添加的列
...
```
### 2. 添加空值处理
使用 `COALESCE` 确保统计字段始终有值:
```sql
-- 防止 NULL 值
COALESCE(s.view_count, 0) as view_count,
COALESCE(s.like_count, 0) as like_count,
COALESCE(s.favorite_count, 0) as favorite_count,
...
```
### 3. 添加列存在检查函数
```sql
CREATE OR REPLACE FUNCTION check_column_exists(table_name TEXT, column_name TEXT)
RETURNS BOOLEAN
LANGUAGE plpgsql
AS $$
BEGIN
RETURN EXISTS (
SELECT 1
FROM information_schema.columns
WHERE table_name = lower(table_name)
AND column_name = lower(column_name)
AND table_schema = current_schema()
);
END;
$$;
```
## 修复的视图
### 1. `vw_media_content_detail`
**包含的列**
- `id` - 主键
- `content_type` - 内容类型
- 所有多媒体字段video_*, audio_*, image_*
- 统计字段(带 COALESCE 处理)
- 用户交互状态is_liked, is_favorited
### 2. `vw_image_content_detail`
**包含的列**
- 基础字段id, content_type
- 图片相关字段
- 图片标签聚合
- 统计字段
- 用户交互状态
### 3. 其他视图
- `vw_video_content_detail` - 继承自主视图,过滤视频内容
- `vw_audio_content_detail` - 继承自主视图,过滤音频内容
## 兼容性说明
### 当前方案优势
**安全性**:只使用确定存在的列
**兼容性**:适用于任何 `ak_contents` 表结构
**可扩展性**:可以根据实际表结构添加更多列
**稳定性**:不会因列不存在而报错
### 如何扩展视图
如果您的 `ak_contents` 表包含更多列,可以手动添加:
```sql
-- 示例:如果您的表有 title 和 content 列
CREATE OR REPLACE VIEW vw_media_content_detail AS
SELECT
c.id,
c.title, -- 如果存在
c.content, -- 如果存在
c.content_type,
c.video_url,
c.audio_url,
c.image_url,
c.images,
c.allow_danmu,
c.allow_download,
c.media_metadata,
COALESCE(s.view_count, 0) as view_count,
-- ... 其他字段
FROM ak_contents c
LEFT JOIN ak_content_statistics s ON c.id = s.content_id;
```
## 使用建议
### 部署步骤
1. **首次部署**:运行修复后的脚本
2. **检查表结构**:使用 `\d ak_contents` 查看实际列
3. **自定义视图**:根据实际需要添加更多列
4. **测试查询**:验证视图是否正常工作
### 检查现有列
```sql
-- 查看 ak_contents 表的所有列
SELECT column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_name = 'ak_contents'
AND table_schema = current_schema()
ORDER BY ordinal_position;
-- 使用我们的检查函数
SELECT check_column_exists('ak_contents', 'title');
SELECT check_column_exists('ak_contents', 'content');
SELECT check_column_exists('ak_contents', 'excerpt');
```
### 测试视图
```sql
-- 测试视图是否可以正常查询
SELECT * FROM vw_media_content_detail LIMIT 1;
SELECT * FROM vw_video_content_detail LIMIT 1;
SELECT * FROM vw_audio_content_detail LIMIT 1;
SELECT * FROM vw_image_content_detail LIMIT 1;
```
## 后续优化
### 动态视图生成(可选)
如果需要更高级的兼容性,可以创建动态生成视图的函数:
```sql
CREATE OR REPLACE FUNCTION rebuild_content_views()
RETURNS VOID
LANGUAGE plpgsql
AS $$
DECLARE
view_sql TEXT;
BEGIN
-- 根据实际存在的列动态构建视图
view_sql := 'CREATE OR REPLACE VIEW vw_media_content_detail AS SELECT c.id, c.content_type';
IF check_column_exists('ak_contents', 'title') THEN
view_sql := view_sql || ', c.title';
END IF;
IF check_column_exists('ak_contents', 'content') THEN
view_sql := view_sql || ', c.content';
END IF;
-- 添加多媒体字段
view_sql := view_sql || ', c.video_url, c.audio_url, c.image_url';
-- 添加其他必要字段...
view_sql := view_sql || ' FROM ak_contents c LEFT JOIN ak_content_statistics s ON c.id = s.content_id';
EXECUTE view_sql;
END;
$$;
```
修复后的数据库现在可以在任何 `ak_contents` 表结构上安全部署,并且可以根据实际需要进行扩展。