使用 python 在 s3 中自动生成文件名的最佳方法

Best way to generate file names automatically in s3 using python

我有一个 python 脚本,我正在构建一个 doc2vec 模型并将其保存到具有不同版本名称的 s3。
参考截图

现在我数据库中的数据每周更新一次,我需要重新构建包含新数据的 doc2vec 模型。

为此,我在 AWS lambda 中安排了一个脚本,每周一次 运行 python 脚本。

现在我想用 model_name 将模型保存到 s3 中,从本周 "model_d2v_version_008" 开始,然后是下周 "model_d2v_version_009",以此类推。

我曾经在自动化流程之前提供 model_name

def d2v_doc(titles_df):
    tagged_data = [TaggedDocument(words=_d, tags=[str(titles_df['id_titles'][i])]) for i, _d in enumerate(titles_df['doc'])]
    model_d2v = Doc2Vec(vector_size=300,min_count=10, dm=1)
    model_d2v.build_vocab(tagged_data)
    model_d2v.train(tagged_data,epochs=100,total_examples=model_d2v.corpus_count)
    return model_d2v

def save_d2v_to_s3(model,fname):
    model_name = fname
    joblib.dump(model,model_name)
    s3_base_path='s3://sd-flikku/datalake/doc2vec_model'
    path = s3_base_path+'/'+model_name
    command = "aws s3 cp {} {}".format(model_name,path).split()
    print('saving...'+model_name)
    subprocess.call(command)


model_doc = d2v_doc(titles_df)

save_d2v_to_s3(model_doc,"model_d2v_version_007")

现在,由于流程是自动化的,我希望 model_name 保持相同的格式并每周增加版本数。我该怎么做?

使用 YYYYMMDD 的后缀或前缀,正如@john-rotenstein 在评论中所建议的那样,将是一个非常可靠的选择,这是明智的专业程序员的典型选择。

它编码了额外的有用信息。如果失败或异常情况偶尔发生,使一个 运行 发生得更晚、更早或永远不会发生,它们仍然会按照正确的顺序排序,并提供一些关于发生的偏差的提示。 ("Oh, 20200719 is missing. Wasn't that the week of the meteor strike?")

如果系统寿命比预期长,或移动到加速计划(只要仍然不超过每天一次),它们仍会按正确的顺序排序。 (007 形式的数字在达到 1000 时停止以有用的方式排序。)

如果您确实希望每天创建多个模型,则可以使用精确到分钟或秒的后缀(YYYYMMDDHHMMSS,甚至可以使用尾随 'Z' 来提示 UTC) ,例如现在 'model_d2v_version_20200518183227Z'.

如果您需要仅使用 AWS 存储桶信息对所有版本进行计数,它需要与任何其他编号相同的键迭代(以到达最后一项),同时制作其他有用的信息(最早,最新) 在文件名中生动。

进行新的保存只需要准确的系统日期即可。 (而且,虽然时钟错误会导致各种毛茸茸的错误,但现在能够 read/write 到 S3 的系统几乎总是有一个可靠的日期。)确保你不会无意中重复使用一个名字,因此也许破坏先验 运行,需要完全相同数量的检查。 (尽管如此,如果存在多个 systems/processes 以 near-simultaneous/interleaved 方式尝试相同操作的风险,那么风险仍然很小 windows。)

另一方面,如果您真的想使用简单的固定宽度递增版本号,请将上次使用的版本号存储在某处。当您需要一个新名字时...

this_version = last_version + 1
model_name = 'model_d2v_version_{0:03d}'.format(this_version)
# then store this_version somewhere you can read it into last_version later

但是 date/timestamp-based 命名更好:

from datetime import datetime
model_name = 'model_d2v_version_' + datetime.utcnow().strftime('%Y%m%d%H%M%SZ')