Search code examples
pythonmkdir

Python mkdir with parent and exist_ok not creating final directory


The code is looping over data in an sqlite3 database and creating directories to extract information into; however, the very final directory is never created. It should be DCIM/dir1 DCIM/dir2 DCIM...

for row in rows:
        localfile = row[0]
        fileloc = row[1]
        # Skip empty entries
        if not localfile or not fileloc:
                continue
        # Get path location of file, create it, ignore if exists
        path = Path(fileloc)
        mkpath = path.parent.absolute()
        targetpath = os.path.join(os.path.join(os.environ.get("HOME"), mkpath))
        print(f"Creating {targetpath}")
        if not os.path.exists(targetpath):
                #Path(os.path.dirname(targetpath)).mkdir(parents=True, exist_ok=True)
                os.makedirs(os.path.dirname(targetpath), 0o755, True)

I'm sure this is not optimal, yet, but the real issue is that $HOME/DCIM is created but $HOME/DCIM/dir1 etc. The print statement is showing the correct output:

Creating /usr/home/jim/DCIM/dir1
Creating /usr/home/jim/DCIM/dir2
Creating /usr/home/jim/DCIM/dir3
Creating /usr/home/jim/DCIM/dir4

But DCIM is empty. I thought that parent might be overwriting, but that doesn't make sense after trying this with $HOME and reading the documentation. I have a feeling it has something to do with the call to path.parent.absolute(), but if I try using os.path.dirname, I get the same results. Sorry if this was already answered, I found many "how to create directories" but nothing that covers this issue. Also sorry for any formatting issues - this is my first post to this StackOverflow.


Solution

  • Since each value of targetpath is already the absolute path of each directory you want to create, when you call os.path.dirname on it, since the path doesn't end with /, you chop everything to the right of the last / on it (in your case the inner directory).

    So basically you don't need to call os.path.dirname on it, just do:

    os.makedirs(targetpath, 0o755, True)