101

I'm working with django 1.6.5 and python 2.7. I have import feature in my app and I get error:

OSError: [Errno 18] Invalid cross-device link

I have problem with this part of code:

os.rename(db_temp, settings.DATABASES['bookmat']['NAME'])

code in settings:

'bookmat': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': '/my_projects/book/db/bookmat.sqlite3',
},
mark
  • 1,027
  • 2
  • 7
  • 7

2 Answers2

147

os.rename only works if source and destination are on the same file system. You should use shutil.move instead.

butesa
  • 1,603
  • 1
  • 8
  • 4
  • 6
    My version if shutil.move() is actually implemented in terms of os.rename(). Is there another alternative to use? – Kilian Foth Apr 11 '18 at 07:56
  • 4
    I'm using `shutil.move` and still getting this error – Jesbus Jun 06 '18 at 14:09
  • 12
    As Kilian says `shutil.move()` with different file systems gives the same error as `os.rename()`. Easiest to use `shutil.copy()` and `os.remove()` instead. – lane Jun 12 '18 at 07:29
  • 15
    `shutil.move` in Python 3 handles the foreign filesystem correctly by using copy and delete, per [documentation](https://docs.python.org/3/library/shutil.html#shutil.move). – kravietz Jul 16 '18 at 22:07
  • 9
    @kravietz it doesn't handle it properly in my case, at least on python3 with a regular ext4 and a folder mounted with `rclone mount`. – ave Sep 04 '18 at 15:28
  • 1
    @Ave @kravietz I have also seen this: changed from `os.rename()` to `shutil.move()` and get the same `OSError`. And the backtrace shows that it calls `os.rename()` @kilian-foth – Robert P. Goldman Nov 29 '20 at 15:23
  • Or, the actual exception is a different one, and you get shown the trace as `os.rename`, as the implementation tries `os.rename`, and then handles the copy+unlink in the except section. So if another exception occurs within the except-block, you get both exceptions in the stack, e.g. when OSError: [Errno 116] Stale file handle is thrown by the attempt to copy. – Rick Moritz Apr 20 '21 at 15:31
12

rename only works when the source and target names are on the same file system. You probably have different mounts. Otherwise you get that error. You can implement the same effect with a copy and a delete.

vvvvv
  • 25,404
  • 19
  • 49
  • 81
Tiago A.
  • 1,392
  • 1
  • 16
  • 26