Skip to content

Commit

Permalink
Support DatabaseStorage.path for files in database - see #44
Browse files Browse the repository at this point in the history
  • Loading branch information
rhunwicks committed Jul 15, 2021
1 parent 0e61874 commit d9cad30
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 3 deletions.
13 changes: 12 additions & 1 deletion binary_database_files/storage.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,18 @@ def path(self, name):
"""
localpath = self._path(self.get_instance_name(name))
if not os.path.exists(localpath):
raise NotImplementedError
try:
# Load file from database.
f = models.File.objects.get_from_name(name)
# Automatically write the file to the filesystem
# if it's missing and exists in the database.
# This happens if we're using multiple web servers connected
# to a common database behind a load balancer.
# One user might upload a file from one web server, and then
# another might access if from another server.
utils.write_file(name, f.content)
except models.File.DoesNotExist:
raise NotImplementedError
return localpath

def exists(self, name):
Expand Down
14 changes: 12 additions & 2 deletions binary_database_files/tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -322,15 +322,13 @@ class Meta:
self.assertTrue(t1.upload.storage.exists(t1.upload.name))
os.remove(t1.upload.path)
self.assertTrue(t1.upload.storage.exists(t1.upload.name))
self.assertRaises(NotImplementedError, lambda t1: t1.upload.path, t1)
data2 = b"22222222"
open(os.path.join(tmpdir, "dummy.txt"), "wb").write(data2)
t2 = Location2Thing.objects.create(
upload=files.File(open(os.path.join(tmpdir, "dummy.txt"), "rb"))
)
os.remove(t2.upload.path)
self.assertTrue(t2.upload.storage.exists(t2.upload.name))
self.assertRaises(NotImplementedError, lambda t2: t2.upload.path, t2)
self.assertEqual(File.objects.count(), 2)
self.assertEqual(Location2Thing.objects.get(pk=t2.pk).upload.file.read(), data2)
self.assertEqual(Location1Thing.objects.get(pk=t1.pk).upload.file.read(), data1)
Expand Down Expand Up @@ -405,6 +403,18 @@ def test_reading_file(self):
self.assertEqual(response["content-type"], "text/plain")
self.assertEqual(response["content-length"], "10")

def test_path_for_file_from_database(self):
call_command("loaddata", "test_files.json")
self.assertEqual(File.objects.count(), 1)
test_fqfn = os.path.join(DIR, "media", "1.txt")
os.remove(test_fqfn)
# File only exists in the database at this point
self.assertFalse(os.path.exists(test_fqfn))
storage = DatabaseStorage()
self.assertEqual(storage.path("1.txt"), test_fqfn)
# File now exists in the filesystem so that it can be accessed directly
self.assertTrue(os.path.exists(test_fqfn))

def test_serve_file_from_database(self):
call_command("loaddata", "test_files.json")
self.assertEqual(File.objects.count(), 1)
Expand Down

0 comments on commit d9cad30

Please sign in to comment.