sqlalchemy @hybrid_property выражения для папки и имени файла из filepath. Очень легко писать в чистом виде python - PullRequest
0 голосов
/ 18 февраля 2020

У меня есть база данных, с которой я использую sqlalchemy, которая включает в себя сохранение местоположения файлов.

У меня есть что-то вроде:

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))

Как бы я go о записи атрибутов @filename.expression и @folder.expression, которые в настоящее время отображаются с неполными реализациями?

1 Ответ

0 голосов
/ 19 февраля 2020

Вот решение, к которому я пришел, и которое я нашел по предложенной ссылке @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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...