filepath中文件夹和文件名的sqlalchemy@hybrid_属性表达式。很容易用纯python编写
我有一个使用sqlalchemy的数据库,其中包括存储文件的位置 我有点像:filepath中文件夹和文件名的sqlalchemy@hybrid_属性表达式。很容易用纯python编写,python,database,sqlite,orm,sqlalchemy,Python,Database,Sqlite,Orm,Sqlalchemy,我有一个使用sqlalchemy的数据库,其中包括存储文件的位置 我有点像: class FileLocation(ORMBase): id = Column('id', Integer, primary_key=True) filepath = Column('filepath', String) 我想添加文件夹和文件名的混合表达式,对应于每个文件路径。当然,使用常规python字符串很容易做到这一点,但我找不到在sqlalchemy表达式中进行此类字符串操作的方法 fro
class FileLocation(ORMBase):
id = Column('id', Integer, primary_key=True)
filepath = Column('filepath', String)
我想添加文件夹和文件名的混合表达式,对应于每个文件路径。当然,使用常规python字符串很容易做到这一点,但我找不到在sqlalchemy表达式中进行此类字符串操作的方法
from sqlalchemy import func
class FileLocation(ORMBase):
id = Column('id', Integer, primary_key=True)
filepath = Column('filepath', String)
@hybrid_property
def folder(self):
return os.path.dirname(self.filepath)
@folder.expression
def folder(cls):
# How to get folder for sql queries???
last_pathsep_index = # ???
return func.substr(cls.filepath, 0, last_pathsep_index)
@hybrid_property
def filename(self):
return os.path.basename(self.filepath)
@filename.expression
def filename(cls):
# How to get filename for sql queries???
last_pathsep_index = # ???
return func.substr(cls.filepath, last_pathsep_index+1, func.len(cls.filepath))
我该如何编写
@filename.expression
和@folder.expression
属性,这些属性目前显示为未完成的实现?以下是我最终得到的解决方案,我通过@AnthonyCarapetis'建议的链接找到了
这最终更像是一个直接的SQL(SQLite)问题,而不是关于sqlalchemy的问题,但我将把sqlalchemy代码留在这里,以防它对其他人有所帮助
import os
import sqlalchemy as sa
from sqlalchemy import case, func
def getpathsep(osname=os.name):
"""use os.name to determine osname"""
return case([(osname == 'nt', '\\')], else_='/')
def dirname(filepath, osname=os.name):
"""use os.name to determine osname"""
pathsep = getpathsep(osname)
replaced = func.replace(filepath, pathsep, '')
filename = func.rtrim(filepath, replaced)
return func.substr(filepath, 0, func.length(filename))
def pathsplit(filepath, osname=os.name):
"""use os.name to determine osname"""
folder = dirname(filepath, osname)
l = func.length(folder) + 1 # add 1 for (back) slash char
basename = func.substr(filepath, l + 1) # First index is 1
return folder, basename
def basename(filepath, osname=os.name):
"""use os.name to determine osname"""
return pathsplit(filepath, osname)[1]
class FileLocation(ORMBase):
id = Column('id', Integer, primary_key=True)
osname = Column('osname', String)
filepath = Column('filepath', String)
@hybrid_property
def folder(self):
return os.path.dirname(self.filepath)
@folder.expression
def folder(cls):
return dirname(cls.filepath, cls.osname)
@hybrid_property
def filename(self):
return os.path.basename(self.filepath)
@filename.expression
def filename(cls):
return basename(cls.filepath, cls.osname)
在这一点上,这实际上只是一个SQL问题——您只需要用SQL方言编写函数来提取字符串的所需部分,然后使用func将它们转换为sqlalchemy。如果简化问题以删除sqlalchemy引用,您可能会更幸运地得到有用的答案。既然您标记了这个sqlite,也许这会有所帮助@AnthonyCarapetis我通过你的链接找到了解决方案。非常感谢。由于您使用的是SQLite,因此可以创建调用相同Python函数的UDF: