【问题标题】:When I append an item to a list with existing items in there, it just overides it and replaces the existing item当我将一个项目附加到其中包含现有项目的列表时,它只是覆盖它并替换现有项目
【发布时间】:2020-11-13 16:09:45
【问题描述】:

我的问题是当我使用该命令一次时,它给了我一条鱼,但如果我再次使用它,它会用最新的一条鱼替换之前的鱼。它应该将自己添加到列表中,而不是覆盖它。下面,kind 是列表。每次我使用该命令时,都应该将一条鱼附加到该列表中

async def fish(ctx, *, msg: str):
    level = 1
    storage = []
    cash = 0
    kind = []
    fishes = 0

    name = ctx.author.name
    guild_id = ctx.guild.id
    user_id = ctx.author.id
    large_chance = ['Carp', 'Salmon', 'Frog']
    medium_chance = ['Catfish', 'Eel', 'Large Bass']
    small_chance = ['Angelfish', 'Blobfish', 'Shark']

    cursor.execute("SELECT fish FROM fishing WHERE user_id = %s AND guild_id = %s",
                   (user_id, guild_id))
    result1 = cursor.fetchone()
    if result1 is None:
        cursor.execute(
            "INSERT INTO fishing (name, user_id, guild_id, fish, kind) VALUES (%s, %s, %s, %s, %s)",
            (name, user_id, guild_id, fishes, kind))
        conn.commit()
    elif result1 is not None:
        if msg == 'fish':
            y = random.randint(0, 100)
            if y >= 30:
                small = random.choice(large_chance)
                embed = discord.Embed(title='Fishing Game',
                                      color=ctx.author.color)
                embed.set_thumbnail(url=ctx.author.avatar_url)
                embed.add_field(name='You caught a common fish', value=f'You caught a {small}')
                embed.add_field(name="Worth:", value="$5")
                await ctx.send(embed=embed)
                kind.append(small)
                fishes = result1[0] + 1
                await ctx.send(kind)
                cursor.execute("UPDATE fishing SET kind = %s, fish = %s WHERE user_id = %s AND guild_id = %s",
                               (kind, fishes, user_id, guild_id))
                conn.commit()

【问题讨论】:

  • 也许您应该只将相关代码发布到您的问题,而不是整个代码。只是查明你的问题。仅在您遇到问题的地方发布代码块。
  • 您也应该始终提供minimal reproducible example,它不是很清楚您的问题是什么。如果您提供示例会有所帮助
  • 表 fishes 的架构是什么?具体有哪些数据类型?
  • @AdrianKlaver 数据类型如下:name: text, user_id: bigint, guild_id: bigint, fish: int, kind: text

标签: python postgresql discord.py


【解决方案1】:

这里有几个问题。第一个是@Silas Hayes-Williams 提到的,即每次运行该函数时都将kind 重置为一个空列表。因此,您一次只能在列表中找到一种鱼。第二个问题是您将列表存储在文本字段中。这意味着什么,请参阅 psycopg2 文档中的 List。简短的版本是:

['Carp'] 
# Becomes
'{Carp}'

在检索时,除非您执行以下操作:

cur.execute("select kind::varchar[] from fishing")

这将导致返回一个您可以使用的列表。最后一件事是您必须在上面添加一些代码,为用户检索现有的kind(根据@Silas Hayes-Williams)并使用它来追加。

【讨论】:

    【解决方案2】:

    每次运行命令时,您都在重新定义 kind。而是尝试从您正在使用的数据库中读取用户当前 kind 并将其设置为要使用的变量

    cursor.execute("SELECT kind FROM fishing WHERE user_id = %s AND guild_id = %s",
                       (user_id, guild_id))
    kind = cursor.fetchone()
    

    使用它而不是 kind=[] 应该可以工作!

    【讨论】:

    • 请参阅下面我的回答,了解上述内容需要修改的原因。
    • @Silas Hayes-Williams 嘿!非常感谢,但它说你不能附加到元组。我知道它们是不可变的,但我该如何改变呢?显然 cursor.fetchone() 是一个元组..
    • @AdrianKlaver 谢谢!我之前没有太多在数据库中存储列表的经验
    • @HankHill。是的,psycopg2 默认返回一个元组(fetchone())或一个元组列表(fetchall())cursor。这可以通过使用不同的cursor factory 进行更改,但这无助于解决将 Python 列表作为 Postgres 数组存储在文本字段中的潜在问题。一种解决方案是我在回答中显示的内容。另一种是将kind字段设为varchar数组类型字段
    猜你喜欢
    • 2015-01-31
    • 1970-01-01
    • 2018-03-27
    • 2012-04-24
    • 2021-08-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-22
    • 2014-03-05
    相关资源
    最近更新 更多