Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Legacy Model Pickle Serialization #3271

Merged

Conversation

phil-lopreiato
Copy link
Member

@phil-lopreiato phil-lopreiato commented Jan 9, 2021

This is the followup to #3234

It implements the write side, as well as some other bug fixes and cleanup. Also adds tests to assert that we can do a round trip serialize + deserialize and get the original value back.

This includes some of the serialization code from the legacy runtime, which maintains its original license. I made the basic modifications to port it to py3, and left links to where to find the original to make future debugging easier.

I also verified that I could take pickles generated by these unit tests and be able to deserialize them in the legacy app's console. After fixing imports, of course. Which we'll need to add to the py2 code anyway.

import base64
import pickle
import io
import pprint

class ImportFixingUnpickler(pickle.Unpickler):
    def find_class(self, module, name):
        renamed_module = module
        prefix = "backend.common."
        if module.startswith(prefix):
            renamed_module = module[len(prefix):]

        return pickle.Unpickler.find_class(self, renamed_module, name)

b64 = "gAJdcQBjYmFja2VuZC5jb21tb24ubW9kZWxzLm1lZGlhCk1lZGlhCnEBKYFxAmNfY29kZWNzCmVuY29kZQpxA1g6AQAAakFqDnRiYXR2LXByb2QtaHJkci8LEgVNZWRpYSIkaW5zdGFncmFtLXByb2ZpbGVfdGl0YW5pdW10aWdlcnM0ODI5DHIYCAcaB2NyZWF0ZWQgACoJCMKYw7bCicKpwq3DncOtAnISGgxkZXRhaWxzX2pzb24gACoAcicIDxoLZm9yZWlnbl9rZXkgACoUGhJ0aXRhbml1bXRpZ2VyczQ4MjlyFxoPbWVkaWFfdHlwZV9lbnVtIAAqAggHchoaFHByaXZhdGVfZGV0YWlsc19qc29uIAAqAHI0GgpyZWZlcmVuY2VzIAEqJGNqDnRiYXR2LXByb2QtaHJkc3oEVGVhbcKKAQdmcmM0ODI5dGRyGAgHGgd1cGRhdGVkIAAqCQjCpcO2wonCqcKtw53DrQJyChoEeWVhciAAKgBxBFgGAAAAbGF0aW4xcQWGcQZScQdiYS4="

p = ImportFixingUnpickler(io.BytesIO(base64.b64decode(b64))).load()
pprint.PrettyPrinter(indent=4).pprint(p)

This gives

[   Media(key=Key('Media', 'instagram-profile_titaniumtigers4829', app='tbatv-prod-hrd'), created=datetime.datetime(2020, 12, 20, 20, 3, 17, 962520), details_json=None, foreign_key=u'titaniumtigers4829', media_type_enum=7, private_details_json=None, references=[Key('Team', 'frc4829', app='tbatv-prod-hrd')], updated=datetime.datetime(2020, 12, 20, 20, 3, 17, 962533), year=None)]

@codecov
Copy link

codecov bot commented Jan 9, 2021

Codecov Report

Merging #3271 (8399e84) into py3 (4984844) will decrease coverage by 0.86%.
The diff coverage is 74.27%.

Impacted file tree graph

@@            Coverage Diff             @@
##              py3    #3271      +/-   ##
==========================================
- Coverage   95.52%   94.65%   -0.87%     
==========================================
  Files         371      375       +4     
  Lines       16899    17576     +677     
==========================================
+ Hits        16143    16637     +494     
- Misses        756      939     +183     
Impacted Files Coverage Δ
...legacy_protobuf/legacy_gae_entity_model_encoder.py 58.91% <58.91%> (ø)
...kend/common/legacy_protobuf/legacy_gae_protobuf.py 63.28% <63.28%> (ø)
...on/legacy_protobuf/legacy_gae_entity_pb_encoder.py 81.00% <81.00%> (ø)
...legacy_protobuf/legacy_gae_entity_model_decoder.py 86.58% <86.58%> (ø)
src/backend/common/models/cached_model.py 100.00% <100.00%> (+11.57%) ⬆️
src/backend/common/models/cached_query_result.py 100.00% <100.00%> (ø)
...es/tests/cached_query_result_compatibility_test.py 100.00% <100.00%> (ø)
... and 1 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4984844...8399e84. Read the comment docs.

@phil-lopreiato phil-lopreiato merged commit 250c717 into the-blue-alliance:py3 Jan 9, 2021
@phil-lopreiato phil-lopreiato deleted the write-legacy-pickles branch January 9, 2021 01:50
phil-lopreiato added a commit that referenced this pull request Jan 24, 2021
This is the py2 component of #3271

The diff will let the legacy py2 app successfully read pickled data in `CachedQueryResult` that was written by the py3 app. The only thing we should need to fix on this side is the import paths where we changed the directory of models.

I've tested this in the admin console, and added some tests that deserialize byte strings created by the py3 code

This will need #3340 on the py3 side
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant