How to restore a key accidentally removed from a DataStore?

I ran an accidental GlobalDataStore | Roblox Creator Documentation and an important key had its contents deleted.
I’m trying to restore some previous version, but I can’t understand how it works, the examples don’t show the content stored inside the keys.
Is there any simple way to restore a specific key?

1 Like

To do this you must use DataStore | Roblox Creator Documentation with the name of the key you deleted. Then you can use DataStore | Roblox Creator Documentation with the key name and version identifier (retrieved from the DataStoreObjectVersionInfo | Roblox Creator Documentation instance from the returned DataStoreVersionPages | Roblox Creator Documentation instance using Pages | Roblox Creator Documentation).

Here’s a code sample from the DataStore:ListVersionsAsync documentation page that retrieving a datastore version after a certain date:

local DataStoreService = game:GetService("DataStoreService")
 
local experienceStore = DataStoreService:GetDataStore("PlayerExperience")
 
local time = DateTime.fromUniversalTime(year=2020, month=10, day=09, hour=01, min=42)
 
local listSuccess, pages = pcall(function()
	return experienceStore:ListVersionsAsync("User_1234", nil, time.UnixTimestampMillis)
end)
if listSuccess then
	local items = pages:GetCurrentPage()
 
	for key, info in pairs(items) do
		print("Key:", key, "; Version:", info.Version, "; Created:", info.CreatedTime, "; Deleted:", info.IsDeleted)
	end
end
1 Like

Wait, was this done on a GlobalDataStore | Roblox Creator Documentation or a DataStore | Roblox Creator Documentation instance? If it was on a GlobalDataStore then like @zaydoudou said, there is no method to retrieve it. However, if it was on a DataStore instance then you can use the method I mentioned above.

Yeah, the first thing I tried was running the example code from page DataStore | Roblox Creator Documentation :

local DataStoreService = game:GetService("DataStoreService")
local JogoStore = DataStoreService:GetDataStore('Jogo', 'Jogo')
 local listSuccess, pages = pcall(function()
 	return JogoStore:ListVersionsAsync("Jogo")
 end)
if listSuccess then
	local items = pages:GetCurrentPage()
	for key, info in pairs(items) do
		print("Key:", key, "; Version:", info.Version, "; Created:", info.CreatedTime, "; Deleted:", info.IsDeleted)
	end
end

… and I got this:

 Key: 1 ; Version: 08D95B55B137117B.0000000E21.08D9BB4769B6733E.01 ; Created: 1639076964027 ; Deleted: false
  Key: 2 ; Version: 08D95B55B137117B.0000000E22.08D9BB4A959F247A.01 ; Created: 1639078326184 ; Deleted: false
  Key: 3 ; Version: 08D95B55B137117B.0000000E23.08D9BB53EA892DAD.01 ; Created: 1639082334117 ; Deleted: false
  Key: 4 ; Version: 08D95B55B137117B.0000000E24.08D9BF0DD86B6B9B.01 ; Created: 1639492043603 ; Deleted: false
  Key: 5 ; Version: 08D95B55B137117B.0000000E25.08D9C00BF43458EA.01 ; Created: 1639601182388 ; Deleted: false
  Key: 6 ; Version: 08D95B55B137117B.0000000E26.08D9C00CB311042B.01 ; Created: 1639601502601 ; Deleted: false
  Key: 7 ; Version: 08D95B55B137117B.0000000E27.08D9C00E525E43B7.01 ; Created: 1639602199362 ; Deleted: false
  Key: 8 ; Version: 08D95B55B137117B.0000000E28.08D9C00EA7F2A11E.01 ; Created: 1639602342940 ; Deleted: false
  Key: 9 ; Version: 08D95B55B137117B.0000000E29.08D9C02DE201FA53.01 ; Created: 1639615754747 ; Deleted: false
  Key: 10 ; Version: 08D95B55B137117B.0000000E2A.08D9C088623D8BCB.01 ; Created: 1639654624592 ; Deleted: false
  Key: 11 ; Version: 08D95B55B137117B.0000000E2B.08D9C088C0E51459.01 ; Created: 1639654783395 ; Deleted: false
  Key: 12 ; Version: 08D95B55B137117B.0000000E2C.08D9C08FD2FC231E.01 ; Created: 1639657820223 ; Deleted: false
  Key: 13 ; Version: 08D95B55B137117B.0000000E2D.08D9C0989119CF2B.01 ; Created: 1639661575158 ; Deleted: false
  Key: 14 ; Version: 08D95B55B137117B.0000000E2E.08D9C09A8180AA0A.01 ; Created: 1639662407982 ; Deleted: false
  Key: 15 ; Version: 08D95B55B137117B.0000000E2F.08D9C09BB4C3E974.01 ; Created: 1639662923483 ; Deleted: false
  Key: 16 ; Version: 08D95B55B137117B.0000000E30.08D9C09C3C708E2E.01 ; Created: 1639663151107 ; Deleted: false
  Key: 17 ; Version: 08D95B55B137117B.0000000E31.08D9C09D722CF230.01 ; Created: 1639663670758 ; Deleted: false
  Key: 18 ; Version: 08D95B55B137117B.0000000E32.08D9C09DF4597062.01 ; Created: 1639663889153 ; Deleted: false
  Key: 19 ; Version: 08D95B55B137117B.0000000E33.08D9C0A2D2B741C5.01 ; Created: 1639665980209 ; Deleted: false
  Key: 20 ; Version: 08D95B55B137117B.0000000E34.08D9C15B40C7C960.01 ; Created: 1639745192265 ; Deleted: false
  Key: 21 ; Version: 08D95B55B137117B.0000000E35.08D9C19FE09B93B1.01 ; Created: 1639774666188 ; Deleted: false
  Key: 22 ; Version: 08D95B55B137117B.0000000E36.08D9C1A015327026.01 ; Created: 1639774754419 ; Deleted: false
  Key: 23 ; Version: 08D95B55B137117B.0000000E37.08D9C1A04A1DD16F.01 ; Created: 1639774843203 ; Deleted: false
  Key: 24 ; Version: 08D95B55B137117B.0000000E38.08D9C32A15577A32.01 ; Created: 1639943976373 ; Deleted: false
  Key: 25 ; Version: 08D95B55B137117B.0000000E39.08D9C33CB0DFF8AA.01 ; Created: 1639951968255 ; Deleted: false
  Key: 26 ; Version: 08D95B55B137117B.0000000E3A.08D9C3B33A42D7B7.01 ; Created: 1640002879365 ; Deleted: false
  Key: 27 ; Version: 08D95B55B137117B.0000000E3B.08D9C3B35711CDA8.01 ; Created: 1640002927698 ; Deleted: false
  Key: 28 ; Version: 08D95B55B137117B.0000000E3C.08D9C3B35EB17306.01 ; Created: 1640002940488 ; Deleted: false
  Key: 29 ; Version: 08D95B55B137117B.0000000E3D.08D9C3B3AE35F183.01 ; Created: 1640003073896 ; Deleted: false
  Key: 30 ; Version: 08D95B55B137117B.0000000E3E.08D9C3B3C20EDAF0.01 ; Created: 1640003107195 ; Deleted: false
  Key: 31 ; Version: 08D95B55B137117B.0000000E3F.08D9C3B3DB8D3351.01 ; Created: 1640003149966 ; Deleted: false
  Key: 32 ; Version: 08D95B55B137117B.0000000E40.08D9C3B3EA521D0A.01 ; Created: 1640003174744 ; Deleted: false

Here I have 3 questions:

  1. Where is the value of the key?
  2. How to know the real date/time of the Created field?
  3. Why I don’t see a Deleted: true if my last operation was RemoveASync

The key in this case is just the index of the DataStoreObjectVersionInfo instance in the list returned by the GetCurrentPage function.

The Created field is a Unix Timestamp. It is basically the seconds that have elapsed since the first of January in the year nineteen something.

Also, I found a code sample that restores the closest version on the DataStore | Roblox Creator Documentation documentation page. If it finds any versions, it will set the current version to the most recent.

local DataStoreService = game:GetService("DataStoreService")
 
local experienceStore = DataStoreService:GetDataStore("PlayerExperience")
 
local DATA_STORE_KEY = "User_1234"
 
local maxDate = DateTime.fromUniversalTime(year=2020, month=10, day=09, hour=01, min=42)
 
-- Get the version closest to the given time
local listSuccess, pages = pcall(function()
	return experienceStore:ListVersionsAsync(DATA_STORE_KEY, Enum.SortDirection.Descending, nil, maxDate.UnixTimestampMillis)
end)
if listSuccess then
	local items = pages:GetCurrentPage()
	if table.getn(items) > 0 then
		-- Read the closest version
		local closestEntry = items[1]
		local success, value, info = pcall(function()
			return experienceStore:GetVersionAsync(DATA_STORE_KEY, closestEntry.Version)
		end)
		-- Restore current value by overwriting with the closest version
		if success then
			local setOptions = Instance.new("DataStoreSetOptions")
			setOptions:SetMetadata(info:GetMetadata())
			experienceStore:SetAsync(DATA_STORE_KEY, value, nil, setOptions)
		end
	else
		-- No entries found
	end
end
3 Likes
  1. Try printing out DataStore:GetAsync(info.Version)
  2. Devide the created time by 1000 and use os.clock to format it into a date (%Y is for year, %M is for month, %D is for day and so goes on.)
  3. Im not sure.

it’s showing nil:

	local items = pages:GetCurrentPage()
	for key, info in pairs(items) do
		local value = JogoStore:GetAsync(info.Version)
		print("Key:", key, "; Version:", info.Version, "; Created:", info.CreatedTime, "; Deleted:", info.IsDeleted)
		print('value: ', value)
	end

My bad, try using DataStore:GetVersionAsync(key,info.Version)

1 Like

Thanks, now I can list all versions of my key and its values, also the correct created date/time (not with os.clock):

local LOCALIZATION	= game:GetService('LocalizationService').SystemLocaleId
local function FormatDateTime(TimeStamp, Format)
	return DateTime.fromUnixTimestamp(TimeStamp):FormatUniversalTime(Format, LOCALIZATION)
end

local DataStoreService = game:GetService("DataStoreService")
local DataStore = DataStoreService:GetDataStore('Jogo', 'Jogo')

local listSuccess, pages = pcall(function()
 	return DataStore:ListVersionsAsync("Jogo")
 end)

if listSuccess then
	local items = pages:GetCurrentPage()
	for key, info in pairs(items) do
		local value = DataStore:GetVersionAsync('Jogo', info.Version)
		local created = FormatDateTime(math.round(info.CreatedTime/1000), 'DD/MM/YYYY HH:mm')  
		print("Key:", key, "; Version:", info.Version, "; Created:",  created, "; Deleted:", info.IsDeleted)
		print('value: ', value)
	end
end

So I get:

  Key: 1 ; Version: 08D95B55B137117B.0000000E21.08D9BB4769B6733E.01 ; Created: 09/12/2021 19:09 ; Deleted: false
  value:   ▶ {...}
  Key: 2 ; Version: 08D95B55B137117B.0000000E22.08D9BB4A959F247A.01 ; Created: 09/12/2021 19:32 ; Deleted: false
  value:   ▶ {...}
  Key: 3 ; Version: 08D95B55B137117B.0000000E23.08D9BB53EA892DAD.01 ; Created: 09/12/2021 20:38 ; Deleted: false