attachment_fu在Windows平台下报 Size is not included in the list

本文介绍了一位开发者在将Rails应用从Linux平台迁移到Windows,并使用attachment_fu插件时遇到的问题及解决办法。主要问题包括:上传文件时出现'Sizeisnotincludedinthelist'错误,以及上传到S3时的超时错误。文章提供了详细的解决方案。

 

将rails应用从linux平台迁移到windows2003,并将代理服务器从lighttpd转为了iis,试用了一下,基本正常。

但后台发现上传图片时,报了个错误  Size is not included in the list

中午查了一下,本以为是size超出了限制,发现没有超过,打了下调试信息,发现self.size为0, 但回退再次上传成功,应该是文件在保存上出了问题,

google之,发现有人解决了,用的是size之前sleep 5,晕倒,这解决方案也太随便了。

 

blogpost上有另外一个老外的解决方法,不错。转过来算了,我痛恨gfw.

 

Size is not included in the list

 

 

Fixing attachment_fu on Windows
Like many others, I've encountered issue when developing Rails applications using attachment_fu on Windows. After doing some research, I've come up with the following solution to the problem.
The problem has two parts :
  1. Size is not included in the list error message,
  2. Timeout error when uploading to S3.
Fixing "Size is not included in the list" error message
Some people have reported that there is a timing issue, when trying to get the file size, with Tempfile on Windows. It seems that the size of the file is not properly reported by Windows after writing data to it. Proposed solutions for this problem include :
  1. Sleeping in a loop as long as the file size is 0,
  2. Reading back the entire file in memory.

I think I found a better and less patchy solution for this issue: forcing the OS to flush the file to disk before reading it's size.
Here is the code to do it :

 

require 'tempfile'

class Tempfile

def size

if @tmpfile

@tmpfile.fsync # added this line
@tmpfile.flush
@tmpfile.stat.size

else

0

end

end

end

Doing a flush is not enough... flush will flush the Ruby buffer but the file may not be immediately written to the disk by the OS. Doing the fsync ensure that the file is written to disk by the OS before continuing. After that, Windows will properly report the actual file size.

Fixing the Timeout error when uploading to S3
This issue is related to opening files for reading on Windows. On Windows, you have to open the file in binary mode. So patching attachment_fu is simple :
 
require 'technoweenie/attachment_fu/backends/s3_backend'
module Technoweenie

module AttachmentFu

module Backends

module S3Backend

protected
def save_to_storage

if save_attachment?

S3Object.store(

full_filename,
(temp_path ? File.open(temp_path, "rb") : temp_data), # added , "rb"
bucket_name,
:content_type => content_type,
:access => attachment_options[:s3_access]

)

end
@old_filename = nil
true

end

end

end

end

end

I've also included a fix from someone else (which was not enough in itself to solve my S3 upload problem):

module Technoweenie

module AttachmentFu

# Gets the data from the latest temp file. This will read the file into memory.
def temp_data

if save_attachment?

f = File.new( temp_path )
f.binmode
return f.read

else

return nil

end

end

end

end
Wrapping it up
So I put all this code in lib/attachment_fu_patch.rb and required it in environment.rb.
Problem fixed!
Note, I did not test it on other OSes, but these fixes should not have any adverse effects.
<think>我们被要求解释给定的SQL语句的含义。这些语句是用于在PostgreSQL中向表`t_workorder_change_bill`添加两个字段(如果它们不存在的话),并给这两个字段添加注释。 具体语句如下: 1. `alter table t_workorder_change_bill add if not exists attachment_id VARCHAR(20);` 解释:这条语句是向表`t_workorder_change_bill`中添加一个名为`attachment_id`的字段,其数据类型为`VARCHAR(20)`。`if not exists`条件确保如果该字段已经存在,则不会重复添加,避免错。 2. `alter table t_workorder_change_bill add if not exists attachment_name VARCHAR(255);` 解释:同样,这条语句是向表中添加一个名为`attachment_name`的字段,其数据类型为`VARCHAR(255)`。同样使用了`if not exists`条件,保证安全添加。 3. `comment on column t_workorder_change_bill.attachment_id is '文件id';` 解释:这个语句给字段`attachment_id`添加注释,注释内容为'文件id'。这样在数据库的元数据中,该字段的说明就是'文件id',方便理解字段的用途。 4. `comment on column t_workorder_change_bill.attachment_name is '文件名称';` 解释:同样,这个语句给字段`attachment_name`添加注释,注释内容为'文件名称'。 注意:在PostgreSQL中,`ADD COLUMN IF NOT EXISTS`语法是从9.6版本开始支持的。因此,使用这些语句需要确保PostgreSQL的版本在9.6及以上。 但是,这里有一个潜在的问题:注释语句(`comment on column`)并没有条件判断。如果字段已经存在,我们仍然会给它添加注释,这将会覆盖原有的注释(如果之前有注释的话)。如果之前没有注释,则添加注释;如果有注释,则更新为新的注释。 因此,整个脚本的作用是: - 安全地添加两个字段(如果不存在则添加,存在则跳过) - 确保这两个字段的注释被设置为指定的内容(无论字段是刚刚添加的还是已经存在的) 这种操作通常用于数据库升级脚本中,以确保数据库结构符合预期,同时避免重复执行时因字段已存在而导致的错误。 现在,根据要求,我们需要在回答后提出3-5个相关问题。</think>### 解释您提供的 SQL 语句含义 您提供的 SQL 语句是 PostgreSQL 中用于安全添加字段的标准语法,具体含义如下: #### 1. 字段添加语句 ```sql alter table t_workorder_change_bill add if not exists attachment_id VARCHAR(20); ``` - **含义**:向表 `t_workorder_change_bill` 添加 `attachment_id` 字段 - **条件**:`IF NOT EXISTS` 确保仅当字段不存在时才执行 - **数据类型**:`VARCHAR(20)` 表示最大长度20的可变字符串 ```sql alter table t_workorder_change_bill add if not exists attachment_name VARCHAR(255); ``` - **含义**:添加 `attachment_name` 字段 - **长度**:`VARCHAR(255)` 允许存储最长255字符的文件名 #### 2. 字段注释语句 ```sql comment on column t_workorder_change_bill.attachment_id is '文件id'; ``` - **作用**:为字段添加元数据描述 - **含义**:说明该字段存储的是文件唯一标识符 ```sql comment on column t_workorder_change_bill.attachment_name is '文件名称'; ``` - **含义**:说明该字段存储的是文件显示名称 ### 关键特性说明 1. **安全执行**: - `IF NOT EXISTS` 避免重复添加导致的错误 - 可在升级脚本中重复执行 2. **字段设计**: - `attachment_id`:适合存储文件哈希或UUID等短标识 - `attachment_name`:255长度足够存储大多数文件名 3. **元数据管理**: - 注释有助于数据库文档化 - 提高字段含义的清晰度 ### 与传统写法的对比 | 传统写法 | 您的写法 | |---------|---------| | 直接执行 `ALTER TABLE ... ADD COLUMN` | 使用 `IF NOT EXISTS` 条件 | | 重复执行会错 | 重复执行安全跳过 | | 需要额外检查字段存在性 | 内置存在性检查 | ### 使用场景 - 数据库版本升级脚本 - CI/CD 自动化部署 - 多环境数据库同步 - 需要幂等操作的数据库变更
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值