question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Model.create(...) possibly corrupting other items

See original GitHub issue

I have a database where I store user information. I have an API endpoint using quart (async flask) where I can submit information to be put in a database. I have a weird bug however, where for some reason when I use my discord account’s data, it updates every other user’s data to be the same (except for discord_id which is primary key and also payments linked to that id) and also replaces any further inserts.

This may be a logic error, or could possibly be a peewee error somehow.

Here is an example of how data is changed.

Example 1

Discriminator on insert for person 1: 3606 Discriminator on insert for person x: 0661

Discriminators after person x inserted: 0232, 0232

Example 2

So I thought it was some indexing issue so I tried this:

Discriminator on insert for person 1: 3606 Discriminator on insert for person 2: 0434

Discriminators after person x inserted: 3606, 0434

Discriminator on insert for person x: 0232

Discriminators after person x inserted: 0232, 0232, 0232

This is very confusing to me, as the code to create a new user replaces the data of other users. As you see, person 2 does not change person 1 but person x does. However, this gets even more confusing, as when person 2 is inserted after person x, person 2 has the same data (except for primary key) as person x.

Possible reasons

  • Person x has “()” in their username, which is put in the database (EDIT: after changing my username, nothing changed)
  • Person x is my current user (logic error in code as access token effects somehow?)
  • Past that I do not know

Relevant code

(mind my spaghet code)

@QUART.route(API_PRE + "add_payment", methods=["POST"])
async def add_payment():
    """
    Add a new payment to existing or new user.
    """
    if request.method == "POST":
        request_parameters = await request.get_json(force=True, silent=True)
        discord_id = request_parameters["discord_id"]
        amount_payed_usd = request_parameters["amount_payed_usd"]
        subtype = request_parameters["subtype"]
        pre_payment = request_parameters["pre_payment"]
        if (
            request_parameters["discord_access_token"] is not None
            and discord_id is not None
            and amount_payed_usd is not None
            and subtype is not None
            and pre_payment is not None
        ):
            try:
                member = Member(request_parameters["discord_access_token"], MAIN_BOT)
                if member.is_manager == True:
                    user_data = MAIN_BOT.get_data_from_id(discord_id)

                    last_seen_username = user_data["user"]["username"]
                    print(last_seen_username)
                    last_seen_discriminator = user_data["user"]["discriminator"]
                    print(last_seen_discriminator)

                    # get pfp URL
                    if user_data["user"]["avatar"] is None:
                        last_seen_pfp = ""
                    else:
                        last_seen_pfp = f"https://cdn.discordapp.com/avatars/{discord_id}/{user_data['user']['avatar']}"
                    
                    # find or add user
                    user = User.get_or_none(User.discord_id == discord_id)
                    if user is None:
                        # suspect code
                        user = User.create(
                            discord_id=discord_id,
                            last_seen_username=last_seen_username,
                            last_seen_discriminator=last_seen_discriminator,
                            last_seen_pfp=last_seen_pfp,
                        )
                        debug(f"NEW USER ADDED BY MANAGER ADDITION ({discord_id})")

                    print(vars(user))

                    if pre_payment == True:
                        # pre-payment logic
                        update_q = User.select(User.discord_id==discord_id).update(pre_payment=True, pre_payment_amount_payed_usd=amount_payed_usd)
                        update_q.execute()

                        debug(f"ADDING PRE-PAYMENT ({subtype}) FOR {discord_id}")
                    else:
                        # non pre-payment logic
                        Payment.create(
                            discord_id=discord_id,
                            subtype=subtype,
                            ms_initiated=current_milli_time(),
                            amount_payed_usd=amount_payed_usd,
                        )

                        debug(f"PAYMENT COMPLETED (NOT PRE-PAYMENT) ({subtype}) for user {discord_id}")


                    return jsonify(is_error=False)
                else:
                    return jsonify(is_error=True, error_msg="You do not have the permission to use this endpoint")

            except Exception as error:
                MAIN_BOT.error_to_developer(error, "add_payment()")
                return jsonify(is_error=True, error_msg="Could not add payment (User Discord ID may be invalid)")
        else:
            return jsonify(is_error=True, error_msg="Required data not passed (access token)")

The only two operations here are .create and .update, but the the .update is, first of all, not even run when the bad operation happens (as I do not pass pre_payment as true), but also the update is on a .select(). The only suspect code I see to make a difference is the User.create(…) clause.

Also for further reference, “access token” is a token that managers pass to the API via a web interface (which is checked for appropriate roles), checked by the Member class creation, however this is never referenced again past role check

By the way, it is not an issue about data creation, but one about possible data corruption either by my own error or peewee error, however I cannot conclude anything from this, but I would appreciate any support, thank you.

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:10 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
mkmoisencommented, Apr 20, 2022

@peepopoggers If you prefer the SQL style over the ORM style:

User.update(foo='bar').where(id=user.id)

But if you prefer the ORM style use the regular save like Coleifer mentioned.

1reaction
coleifercommented, Apr 20, 2022

You should probably use the more idiomatic save() instead of update():

user = User.get_or_none(...)
if user is not None:
    user.last_seen... = xyz
    user.save()
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to Fix and Prevent Revit Model Corruption • ATG USA
Here are a few ways we can fix and prevent RVT model corruption and avoid loss of productivity. Update everyone's Revit stations to...
Read more >
How to troubleshoot model corruption in Revit
Audit the project (if possible). · Purge unused elements from the model. · Clear as many warnings as possible. · Unload any linked...
Read more >
Revit Snippet: Fix corrupt model with too many missing elements
Ever had a Revit model with too many missing elements, cannot be opened and just threw this error message? See our exact steps...
Read more >
How to troubleshoot any model corruption (in particular TR3110)
-> Make a copy of the PYJ model and start deleting some objects step-by-step (views, categories, measures, cubes, levels, dimensions, ...
Read more >
What Causes Revit Data Corruption? - Microsol Resources
Element Level Corruption : When elements are modified within a model, the modification can affect other objects which interact with the first ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found