sqlalchemy资产管理器
sqlalchemy-media的Python项目详细描述
文档
有关详细说明,请参见documentation。
为什么?
现在,大多数数据库应用程序都允许用户上传 并将各种类型的文件附加到orm模型。
如果你必须关心安全,处理这些工作就不简单了, 高可用性、可扩展性、CDN和更多您可能已经拥有的东西 一直很担心。接受公共空间的文件,分析,验证, 处理(规范化)并再次将其提供给公共空间是 这个项目的主要目标。
sql炼金术是实现这些功能的最佳平台。它有 SqlAlchemyMutable类型工具可以使用 输入到位。为什么不?
注意
主要思想来自大丽亚的SQLAlchemyImageAttach。
概述
- 存储和定位任何文件,通过sqlalchemy模型跟踪它。
- 存储层与数据模型完全分离,有一个简单的api:(put、delete、open、locate)
- 使用任何连接python字典的sqlalchemy数据类型。这是通过使用 SqlAlchemyTypeDecorators和SqlAlchemyMutable。
- 提供delete_orphan标记以自动删除通过属性集孤立或从中删除的文件 收藏,或者只存在于记忆中的物品!通过将它的最后一个指针设置为“无”。
- 从url、本地文件系统和流附加文件。
- 如果可能,使用magic模块从后端流中提取文件的mimetype。
- 限制文件大小(最小、最大),以防止DoS攻击。
- 在url中添加时间戳以帮助缓存。
- 使用width、height和/或ratio自动生成缩略图。
- 使用magic和wand分析文件和图像。
- 正在验证mimetype、width、height和图像ratio。
- 存储前自动调整图像大小并重新格式化图像。
- 感谢@YukSeungChan,您实现了S3Store和OS2Store。
- ssh/sftp存储
快速启动
下面是一个简单的示例,以了解如何使用此库:
importfunctoolsimportjsonfromos.pathimportexists,joinfromsqlalchemyimportcreate_engine,TypeDecorator,Unicode,Column,Integerfromsqlalchemy.ormimportsessionmakerfromsqlalchemy.ext.declarativeimportdeclarative_basefromsqlalchemy_mediaimportStoreManager,FileSystemStore,Image,ImageAnalyzer,ImageValidator,ImageProcessorTEMP_PATH='/tmp/sqlalchemy-media'Base=declarative_base()engine=create_engine('sqlite:///:memory:',echo=False)session_factory=sessionmaker(bind=engine)StoreManager.register('fs',functools.partial(FileSystemStore,TEMP_PATH,'http://static.example.org/'),default=True)classJson(TypeDecorator):impl=Unicodedefprocess_bind_param(self,value,engine):returnjson.dumps(value)defprocess_result_value(self,value,engine):ifvalueisNone:returnNonereturnjson.loads(value)classProfileImage(Image):__pre_processors__=[ImageAnalyzer(),ImageValidator(minimum=(80,80),maximum=(800,600),min_aspect_ratio=1.2,content_types=['image/jpeg','image/png']),ImageProcessor(fmt='jpeg',width=120,crop=dict(left='10%',top='10%',width='80%',height='80%',))]classPerson(Base):__tablename__='person'id=Column(Integer,primary_key=True)name=Column(Unicode(100))image=Column(ProfileImage.as_mutable(Json))def__repr__(self):return"<%s id=%s>"%(self.name,self.id)Base.metadata.create_all(engine,checkfirst=True)if__name__=='__main__':session=session_factory()withStoreManager(session):person1=Person()person1.image=ProfileImage.create_from('https://www.python.org/static/img/python-logo@2x.png')session.add(person1)session.commit()print('Content type:',person1.image.content_type)print('Extension:',person1.image.extension)print('Length:',person1.image.length)print('Original filename:',person1.image.original_filename)thumbnail=person1.image.get_thumbnail(width=32,auto_generate=True)print(thumbnail.height)assertexists(join(TEMP_PATH,thumbnail.path))thumbnail=person1.image.get_thumbnail(ratio=.3,auto_generate=True)print(thumbnail.width,thumbnail.height)assertexists(join(TEMP_PATH,thumbnail.path))person1.image.attach('https://www.python.org/static/img/python-logo.png')session.commit()print('Content type:',person1.image.content_type)print('Extension:',person1.image.extension)print('Length:',person1.image.length)print('Original filename:',person1.image.original_filename)withStoreManager(session,delete_orphan=True):deleted_filename=join(TEMP_PATH,person1.image.path)person1.image=Nonesession.commit()assertnotexists(deleted_filename)person1.image=ProfileImage.create_from('https://www.python.org/static/img/python-logo.png')session.commit()print('Content type:',person1.image.content_type)print('Extension:',person1.image.extension)print('Length:',person1.image.length)print('Original filename:',person1.image.original_filename)
将产生:
Content type: image/jpeg Extension: .jpg Length: 2020 Original filename: https://www.python.org/static/img/python-logo@2x.png 8 28 7 Content type: image/jpeg Extension: .jpg Length: 2080 Original filename: https://www.python.org/static/img/python-logo.png Content type: image/jpeg Extension: .jpg Length: 2080 Original filename: https://www.python.org/static/img/python-logo.png
示例
签出repo根目录中的examples目录。
分支
一个新的分支模型被应用于这个存储库,它由 主分支和释放分支。
贡献
- 在做任何事情之前记住python的禅(import this)。 最大直线宽度为: