#databases

1 messages · Page 51 of 1

hollow tiger
vestal apex
#

@hollow tiger I can't speak for everyone, but I know I speak for more than one person when I say that the "ping me if you reply" thing is incredibly grating. if it seems like it's been long enough that your attention should be drawn to the channel then anyone with an iota of common sense will do just that. asking people to do so explicitly after every question you ask makes it seem like you don't actually care enough to be present to discuss the issue you're having

#

that being said, what was unclear about the replace documentation I linked you to?

#

why are you deleting subfields of rows anyways? that seems like a poor organizational choice

hollow tiger
#

sorry about trying to hog the channel

#

i've just grown unecessarily impatient because i've been annoyed about this since yesterday

vestal apex
#

hogging the channel has nothing to do with any complaint I've voiced

#

it looks like the biggest issue you have here is that you're trying to do something that no one who wrote rethinkdb documentation expects you to do

#

that's generally a sign that you shouldn't be doing it

#

oh I stand corrected

#

it's there in the docs

#

the page for the method you were asking about using

hollow tiger
#
{  
    "apps":{  
       "Something": {},
       "Other thing":{}
    }
}
#

so i'd do .without({"apps"{"Other thing":{}}})?

hasty hinge
hollow tiger
#

does it matter what :{} is after "Other thing"?

vestal apex
#

that doesn't look like any of the examples in the documentation, Josh

hollow tiger
#

i'm just confused by the example

#

i'm on the page

vestal apex
#

I think the true bit probably implies that the boolean is important

#

or you could use the shorthand

hollow tiger
#

so .without({"apps"{"Other thing":True}}) would be like del document["apps"]["Other thing"]?

vestal apex
#

in theory. give it a try

hollow tiger
#

alright

#

so sorry about any problems that i may have caused

vestal apex
#

it's really just the "ping me if you respond" thing. incredibly frustrating

ionic pecan
#

actually after thinking about it for a moment what I sent is completely bogus, sorry @hasty hinge

#

but I have a better idea

hasty hinge
#

If it is something dangerous or you are not sure, no problem, I already did a backup of my db

ionic pecan
#
test=# SELECT * FROM thing WHERE id = 3 ORDER BY xp LIMIT 1;  -- show top entry
 id | xp 
----+----
  3 |  4
(1 row)

test=# SELECT * FROM thing WHERE id = 3 AND xp != 4;  -- show everything but top entry
 id | xp 
----+----
  3 |  5
  3 |  6
  3 |  7
  3 |  8
  3 |  9
  3 | 10
(6 rows)

test=# BEGIN WORK;  -- transaction for sanity check
BEGIN
test=# DELETE FROM thing WHERE id = 3 AND xp != 4;  -- delete everything but top row
DELETE 6
test=# SELECT * FROM thing WHERE id = 3 AND xp != 4;  -- doesn't have any other entries
 id | xp 
----+----
(0 rows)

test=# SELECT * FROM thing WHERE id = 3;  -- only has top entry
 id | xp 
----+----
  3 |  4
(1 row)

test=# COMMIT;  -- sync to disk
COMMIT
#

that should give you an idea, shouldnt make any difference that its postgres vs mysql

#

maybe you need to just use BEGIN in mysql or something that idk

#

can probably combine the first query and the delete like i did originally

hasty hinge
#

Nice, I will try, thx so much.

hasty hinge
#

Well, I did this:


                await cur.execute("SELECT * FROM USUARIOS WHERE ID = 272407973572116480 ORDER BY XP LIMIT 1;")
                r = await cur.fetchall()
                print(r)
                uid = r[0][0]
                xp = r[0][1]
                print(xp)
                print(uid)                
                await cur.execute("DELETE FROM USUARIOS WHERE ID = {} and xp != {} ;".format(uid, xp))
                await conn.commit()

and it worked, so I think I will first get the whole id list from USUARIOS, and then create a list without duplicated IDs, and for every ID do the up code.

hollow tiger
#

Alright, so I was referencing this article: https://www.rethinkdb.com/api/python/update/
Here is a snippet of the passage under Updating nested fields that I'd like to discuss:

Example: Update Bob Smith’s cell phone number.

r.table("users").get(10001).update(
    {"contact": {"phone": {"cell": "408-555-4242"}}}
).run(conn)```---
This specific example shows how to update a nested dict. How would I go about editing a nested list though?
vestal apex
#

presumably you can use these operations on whatever level of nested field you please

hollow tiger
#

Isn't that appending, not editing? (my bad if it isn't)

vestal apex
#

what form of editing were you hoping for, besides adding and removing elements?

hollow tiger
#

for example, editing the 3rd item of a list - ["hi","bye","what","lol"] nested inside a dict, edited into something like ["hi","bye","edited","lol"]

vestal apex
#

I mean, there's lots of other methods in the sidebar there

#

maybe you can chain some together to pull that off

#

I've never used RethinkDB before I'm literally just perusing the docs

hollow tiger
#

reading documentation has never been my strengths - i'm giving my best attempts here

#

let's see...

vestal apex
#

I see the ones you want in that collection

hollow tiger
#

row
pluck
without
merge
append
prepend
difference

vestal apex
#

not those names specifically

#

the whole Document Manipulation category

hollow tiger
#

that section?

#

oh

#

omg i think i found it

vestal apex
#

👍

hollow tiger
#

let me test it

#

damnit i'm confused again

#

how do i specify what list in which nested dict of a specific document to change for .change_at()?

vestal apex
#

how do you get the list?

hollow tiger
#

the list is nested within a dict in a document

vestal apex
#

how do you get it normally?

hollow tiger
#

so like the example above said that u can update a dict item nested within a document using py r.table("users").get(10001).update( {"contact": {"phone": {"cell": "408-555-4242"}}} ).run(conn)

#

but then this is kinda weird because i'd have to put .change_at() somewhere

#

the docs say it's array.change_at() though which is confusing

vestal apex
#

how do you get the list normally?

hollow tiger
#

i don't know

vestal apex
#

you've never read the contents of the list before?

hollow tiger
#

ohh

#

db.get("423374132873527297").run(conn)["apps"]["Moderator"]["app"]

#

is what i ran to check the list

vestal apex
#

try sticking that up against the get() call instead

#

the indexing

hollow tiger
#

against the get()?

#

like in between get() and .run()?

vestal apex
#

yes

hollow tiger
#

damnit

#

it says ```py
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python3.6/dist-packages/rethinkdb/ast.py", line 123, in run
return c._start(self, **global_optargs)
File "/usr/local/lib/python3.6/dist-packages/rethinkdb/net.py", line 625, in _start
return self._instance.run_query(q, global_optargs.get('noreply', False))
File "/usr/local/lib/python3.6/dist-packages/rethinkdb/net.py", line 471, in run_query
raise res.make_error(query)
rethinkdb.errors.ReqlQueryLogicError: Expected type ARRAY but found OBJECT in:
r.table('guilds').get('423374132873527297').change_at(2, "What's your time zone?")
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

vestal apex
#

it doesn't look like you put the indexing parts up against the get()

hollow tiger
#
>>> db.get("423374132873527297").change_at(2, "What's your time zone?").run(conn)["apps"]["Moderator"]["app"]```
#

do i need the r.expr( and everything maybe?

#

like in the example

vestal apex
#

put them up against the get()

hollow tiger
#

alright

vestal apex
#

app seems like a weird thing to name a list of multiple values

hollow tiger
#

it should be sometihng like ["questions"]

#

interesting - it says [1, 2, "What's your time zone?", 4, 5] in the console now

#
>>> db.get("423374132873527297")["apps"]["Moderator"]["app"].change_at(2, "What's your time zone?").run(conn)
[1, 2, "What's your time zone?", 4, 5]
>>> db.get("423374132873527297").run(conn)["apps"]["Moderator"]["app"]
[1, 2, 3, 4, 5]
#

it didn't update the database though :/

hollow tiger
#

ok so like i've made a solution but this is probably not the best way to do things:

Editing an Application

  1. Get the Questions: questions = db.get(str(ctx.guild.id)).run(conn)["apps"]["Moderator"]["app"]
  2. Edit a Question: questions[2] = "Why?"
  3. Save new Questions: db.get(str(ctx.guild.id)).update({"apps":{"Moderator":{"app":questions}}}).run(conn)

scarlet sand
#

I asked this on the Django discord btu it seems to be dead, so this seems like the best place. I have my Django project running on Elastic Beanstalk with a local SQLite database. Instead of using RDS, is it possible that I put the SQLite DB on S3?

hollow tiger
#

hey, rethinkdb is kinda saving my integers weirdly, like this: 4.59310207101567e+17

#

i've compared the actual int i was saving to int(4.59310207101567e+17) and for some weird reason it wasn't the same

#

how would i retrieve the original?

dull scarab
#

It's not an integer?

hollow tiger
#

hmm.... that's weird

#

because when i did int(4.59310207101567e+17)

dull scarab
#

It converts to an integer.

#

Which probably gave you 29?

hollow tiger
#

the really weird part though is the fact that i was trying to save 459310207101566977

marsh knot
#

eval

hollow tiger
#

i can do it in the console if u want

dull scarab
#

Are you saving it as a int32 then?

hollow tiger
#
>>> int(4.59310207101567e+17)
459310207101566976```
dull scarab
#

Cause then it probably goes past the max int

hollow tiger
#

i didn't specify anything to save it in

#

does it have a default of "int32"?

dull scarab
#

For the database

hollow tiger
#

hmm...

#

i am saving the id of a discord channel

#

i'm still confused on how saving 459310207101566977 somehow magically becomes 459310207101566976

dull scarab
#

The result seems about right, as 4.59...e+17 is equivalent to 4.59... * 10 **17

#

It's probably floating points being weird

#

Try converting the id to a string, and back t int when you load it

hollow tiger
#

that's a smart idea

torn sphinx
#
@client.command(pass_context=True)
async def leaderboard(ctx):
    res1 = c.execute("SELECT Coins FROM Users ORDER BY Coins DESC;")
    res1 = res1.fetchone()
    embed = discord.Embed(title="Most coins", description="The top users with the most Coins", color=0xfffafa)
    res2 = c.execute("SELECT UserID FROM Users ORDER BY Coins DESC;")
    res2 = res2.fetchone()
    for counter in range(0, 1):
        for member in ctx.message.server.members:
            counter_id = str(res2[counter])
            if counter_id == member.id:
                print(str(res1[counter]))
                embed.add_field(name=member.display_name, value=str(res1[counter]), inline=False)
                break
    await client.say(embed=embed)
#

this is database SQL

#

for my bot

#

But the thing is I want it to show 2 people

#

in the database

#

I use the DB Broswer

#

`Ignoring exception in command leaderboard
Traceback (most recent call last):
File "C:\Users\BODZIO\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 50, in wrapped
ret = yield from coro(*args, **kwargs)
File "C:\Users\BODZIO\Desktop\Discord Bot\DiscordBot.py", line 198, in leaderboard
counter_id = str(res2[counter])
IndexError: tuple index out of range

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "C:\Users\BODZIO\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\bot.py", line 846, in process_commands
yield from command.invoke(ctx)
File "C:\Users\BODZIO\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 374, in invoke
yield from injected(*ctx.args, **ctx.kwargs)
File "C:\Users\BODZIO\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 54, in wrapped
raise CommandInvokeError(e) from e
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: IndexError: tuple index out of range
Ignoring exception in command None
discord.ext.commands.errors.CommandNotFound: Command "leadearboard" is not found`

#

this is the error I get

#

even if 2 people are in the db

spiral burrow
#

Well you can start with the obvious typo from the second traceback

hasty hinge
#
                print(type(level))
                print(type(warnid))
                print(type(user))
                print(type(author))
                print(type(reason))
                await cur.execute("INSERT INTO WARNS(WARNID, LEVEL, USERID, AUTHORID, REASON) VALUES ({}, {}, {}, {}, {}, '{}')".format(warnid, level, user, author, reason))

I don't know why I'm getting an IndexError

pseudo compass
#

6 brackets instead of 5

#

remove one

dull scarab
#

You specified 5 columns, so you gotta provide 5 variables (brackets)

hasty hinge
#

I didn't see that, thx.

dull scarab
#

Also, you probably shouldn't format your query with string manipulation

#

Security risks and all that

pseudo compass
#

^^^

dull scarab
#

Which database are you using

hasty hinge
#

Which database?

dull scarab
#

What are you using to interact with your database

#

sqlite, mysql, postgres e.g

hasty hinge
#

Mysql

#

And the python module that I am using is aiomysql

dull scarab
#

Use prepared statements instead, if i recall correctly it's %s for variables in mysql

#
cursor.execute(
    "INSERT INTO sometable(col1, col2) 
        VALUES( %s, %s );", some_variable, variable2)```
hasty hinge
#

What is the .format() vulnerable to?

dull scarab
#

Inserting sql queries directly

pseudo compass
#

sql injection

dull scarab
#

Say your query was py "SELECT * FROM users WHERE id=" + arg + ";"

#

If arg was set to " or 1=1 or "" = "

#

It would give every entry

#

as a simple example

hasty hinge
#

But what if I use some queries only for my code?

dull scarab
#

wdym

hasty hinge
#

I use some defs only for my own code, without user parameters.

#

But, now that I am thinking that, it looks dangerous

#

In my db I don't have passwords or private rows, but my db can be deleted from there, right?

dull scarab
#

Any thing could alter it with that form of input

#

And they could delete your table, get it, alter it etc

#

Just having a name be an sql query could drop your table, if you store their names this way

pseudo compass
#

if you are vulnerable to sql injection, they can run any query your db supports

dull scarab
#

in your case REASON could be a query

hasty hinge
#

Yeah, it is a string

dull scarab
#

The others are ids provided by the code. Bit harder to alter

gusty spindle
hasty hinge
#

Yeah, because them are user parameters that the user can't change.

dull scarab
#

Nontheless, use prepared statements, better safe than sorry

hasty hinge
#

Well, so for example, I have this query, how can I make it safer with %s?

await cur.execute("UPDATE USUARIOS SET XP = XP + {}, GC = GC + {} WHERE ID = {}".format(newxp, newgc, user.id))
dull scarab
#

replace {} with %s

#

and instead of .format add the variables as parameters to execute itself

hasty hinge
#

I am seeing this example @dull scarab, but why in some places is %s and in others %d or %c?

dull scarab
#

That's using old string formatting

#

Not prepared statements

#
execute("select * from users where name = %s and age = %s", name, age)```
#

There's no % after the string

#

it's just a query (as a string with %s) and arguments to execute

hasty hinge
#

Ohh, I understand

rancid pier
#

be very careful not to accidentally do string interpolation when building queries with ORM

#

It's a giant security risk, always make sure they're passed as parameters to functions

#

Thought I'd throw this out there and save some lives

vestal apex
#

we really should just have a tag for it at this point

hasty hinge
#

So, I can just use %s for all my vars? @dull scarab

dull scarab
#

If you think you could use string manipulation, then say no and use prepared statements %s

hasty hinge
#

Well, I also need to make safer my functions, like with filters if a input is not an int, or a string.

#

Thx, you solved my questions.

dull scarab
rancid pier
#

@gusty spindle that xkcd is one of my favourites of all time

gusty spindle
#

haha, yup

hasty hinge
#

@dull scarab I tried to pass all my code to %s, but I am getting this error:

Ignoring exception in on_message
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/discord/client.py", line 220, in _run_event
    await coro(*args, **kwargs)
  File "botSQL.py", line 836, in on_message
    await upduser(message.author, newxp=randomxp, newgc=0.01)
  File "/home/ubuntu/Bot/sqlcalls.py", line 52, in upduser
    await cur.execute("UPDATE USUARIOS SET XP = XP + %s, GC = GC + %s WHERE ID = %s", newxp, newgc, user.id)
TypeError: execute() takes from 2 to 3 positional arguments but 5 were given
torn sphinx
#

maybe they need to be a tuple

#

like python await cur.execute("UPDATE USUARIOS SET XP = XP + %s, GC = GC + %s WHERE ID = %s", (newxp, newgc, user.id))

dull scarab
#

That's very possible

hasty hinge
#

I will try

dull scarab
#

Yeah, can confirm. You need to pass the variables as a tuple

#

even if it's one variable like: (var,)

hasty hinge
#

Now I am getting other error: I don't know if it is related with the tuples but before when I was using .format() it was working.

Traceback (most recent call last):
  File "/usr/local/lib/python3.6/dist-packages/discord/ext/commands/core.py", line 61, in wrapped
    ret = await coro(*args, **kwargs)
  File "/home/ubuntu/Bot/ghsSQL.py", line 282, in top
    for a, b, c in usort:
ValueError: too many values to unpack (expected 3)

This is my code @dull scarab

torn sphinx
#

well each item in usort should have 3 items

#

for ex each item in usort can be a tuple that consists of 3 items

dull scarab
#

Try printing usort, see it matches what you expect it to be

obsidian leaf
#

is there a way of searching an array in a database? say i had a field called list with a data like ["apple","orange"] is there a way of searching for apple or is there a better way to do it?

#

sounds really stupid to say but i hope one of you get what i mean xD

spiral burrow
#

Do you actually have this database or is this a theoretical question

obsidian leaf
#

i have a database with like school classes in which is basically the same question

#

but im not sure how to do it

ionic pecan
#

how are the arrays stored in the database?

obsidian leaf
#

theyre not yet

#

so is it impossible xD

ionic pecan
#

well you can store arrays in some databases

#

but the usual way is just something like

#
user_id | fruit
--------+------
1       | apple
1       | orange

instead of storing a list on each entry

#

if only discord supported tables

obsidian leaf
#

ohhh shit

#

thats a great idea

#

ty

hollow tiger
#

hey, i've recently decided that i'd switch from individual json documents to document databases were a good idea. After switching over, my bot's response time has more than doubled. Is there a common cause to this?

dull scarab
#

A lot of db actions?

hollow tiger
#

i'm not sure, this is for a discord bot and the discord bot is in approximately 2000 servers at the moment

#

but for some reason, with the same amount of servers, the ping has more than doubled after switching to databases

#

i'm using rethinkdb by the way

#

import rethinkdb as r
bot.conn = r.connect(db="appbot")
db = r.table("guilds")

async def get_data(guild_id):
    data = db.get(str(guild_id)).run(bot.conn)
    if data is not None:
        return data
    else:
        data = {"id":str(guild_id),"apps":{},"members":{},'DM':True, 'blacklist':[], 'logs': None, 'archives': None, 'appeditroles': [], 'appreviewroles': []}
        db.insert(data).run(bot.conn)
        return data 

async def save_data(guild_id,data):
    db.get(str(guild_id)).update(data).run(bot.conn)
#

^ that's my main way of getting and saving data, at least at the moment.

#

i've also used the same formula for json docments

dull scarab
#

Doesnt tell me much about how much you interact with it

low lion
#

Well, the fastest way to grab data is from a built-in data structure, like a dict. If you were loading the jsons once, and storing it in a dictionary, but you're constantly working with the new database, that could be the cause, but that would be an odd design decision, and as you said, you didn't really change much.

hollow tiger
#

if i didn't really change much, how would i explain having the ping doubling? 🤔

dull scarab
#

Id do like corin says and try to keep stuff cached

low lion
#

It's on a locally hosted db?

dull scarab
#

How do you check the ping

hollow tiger
#
  1. /ping
  2. send "pong! loading..."
  3. subtract from time sent * 1000 + "ms"
low lion
#

Hm.

hollow tiger
#

the weird thing is that it also spikes, just like the old json documents.

#

i did this just now

low lion
#

I'd try to systematically break down the command, piece by piece, and time each part.

hollow tiger
#

break down /ping?

low lion
#

I'm thinking more connection codes, prefix checking (if you have it), and the like.

dull scarab
#

Well, it most likely because you await the first send allowing another process to continue, and depending on how blocking those it may not be able to return fast enough

low lion
#

Also ^

hollow tiger
#

i do have prefix checking

#

but i preload prefix.json into a global dict

low lion
#

I meant live prefix checking, so that's probably fine.

hollow tiger
#

so now, "await the first send allowing another process to continue, and depending on how blocking those it may not be able to return fast enough"

#

the only blocking thing i can think of at the moment is the document database

#

the previous version that used json was using aiofiles, which asynchronously loads files

low lion
#

If you get a timing module, you could test each command on its own. Since your pings are disparate, it's likely that only some of the commands are the culprit.

hollow tiger
#

maybe

#

something else i've noticed was that running this on a test bot is consistently way faster

#

less servers, less executed commands

dull scarab
#

Most non awaited tasks are in a way blocking

low lion
#

^

dull scarab
#

Did you have custom prefixes?

hollow tiger
#

yes

#

i did

#

shall i send the code i have for it?

dull scarab
#

Is it loading a json / db request on every message?

hollow tiger
#

no

#

at the beginning i preload a prefix.json into a variable

#

it's a huge dict formatted like

#
{
     guild_id: [list,of,prefixes]
}```
dull scarab
#

Ok, well thats the general thought process you gotta follow for most of your commands and events

hollow tiger
#

load the whole db beforehand? D:

dull scarab
#

Events may seem like they run on the side for instance, but they occupy the same event loop

#

No, think about what a command does, how many time consuming tasks does it have, how often does it return to the event loop, how often I the command used

vestal apex
#

you could try enabling event loop debugging and having it fire a warning on long-running coroutines

hollow tiger
#

event loop debugging? that sounds like something i want to try out

#

how does that work?

hollow tiger
#

i do have a couple of asynchronous but long lasting commands

#

my bot has a /config command which brings up like a config menu, waiting for reactions

#

there is a timeout of a minute

low lion
#

That, uh, might cause issues.

hollow tiger
#

isn't it asynchronous?

low lion
#

What do you mean by a timeout?

hollow tiger
#

async def waitrct(ctx, message, reactions):
    def rctcheck(reaction,user): 
        return reaction.message.id == message.id and user == ctx.message.author and str(reaction.emoji) in reactions
    reaction, user = await bot.wait_for('reaction_add',timeout=300.0,check=rctcheck)
    return str(reaction.emoji)```
#

ok apparently the timeout is 5m lol

#

isn't it asynchronous tho?

vestal apex
#

that's a little different

#

you'd be looking for things that block the event loop for long periods of time

#

that doesn't block the event loop

hollow tiger
#

and also, i've had the exact same thing when i used json documents - after switching to dbs, nothing has changed but how the data has saved

#

blocking the event loop 🤔

vestal apex
#

do you remember when I explained to you how asyncio wasn't doing multiple things at the same time, just switching between little pieces of stuff very fast?

hollow tiger
#

how long ago was this 😂

vestal apex
#

the event loop handles scheduling and executing all those tasks. if one of them takes a really long time, every other scheduled task has to wait for it to finish

#

few months

hollow tiger
#

your memory is incredible

#

that's interesting

#

is the bot's rotating status a cause?

#
async def presence():
    await bot.wait_until_ready()
    cycle = itertools.cycle(['apps for {} users'.format(len(bot.users)),'apps for {} servers'.format(len(bot.guilds)),'for @AppBot help'])
    while not bot.is_closed():
        await bot.change_presence(activity=discord.Activity(name=next(cycle),type=discord.ActivityType.watching))
        await asyncio.sleep(10)

bot.loop.create_task(presence())```
dull scarab
#

Probably has correlation to the statement, you learn something better if you try to teach it to others

vestal apex
#

teaching has taught me everything I know better than I ever knew it

#

that doesn't look like a task that would take up much time

low lion
#

The problem is probably not a bunch of repeated await statements.

dull scarab
#

^

#

Id look for the opposite

hollow tiger
#

from what i see, i don't feel that i have a lot of repeated await statements

#

or i do**

low lion
#

In all likelihood, it's a long running, non-awaited (i.e. not async) statement.

hollow tiger
#

i have a ton of repeated await statements, but i don't remember putting non-awaited statements anywhere

vestal apex
#

you need to identify pieces of your code that are going a long time without ever giving control back to the event loop. await explicitly gives control back to the event loop

#

really this is what the debugging mode is for

hollow tiger
#

i've never done debugging before

low lion
#

I'm referring to things like py cycle = itertools.cycle(['apps for {} users'.format(len(bot.users)),'apps for {} servers'.format(len(bot.guilds)),'for @AppBot help'])
That statement in particular is probably not the actual cause but something without await is probably causing you the hassle. But yes, try the debugging.

vestal apex
#

that's why I linked it to ya

hollow tiger
#

i've always hesitated on debugging because it looked so complicated, but if it's for the better, i'm down to learn

#

• Enable the asyncio debug mode globally by setting the environment variable PYTHONASYNCIODEBUG to 1, using -X dev command line option (see the -X option), or by calling AbstractEventLoop.set_debug().

low lion
#

It's definitely better than just putting print everywhere.

hollow tiger
#
  • PYTHONASYNCIODEBUG* -X AbstractEventLoop.set_debug()
vestal apex
#

asyncio.get_event_loop().set_debug() at the top of your main script would probably do the trick

hollow tiger
#

that's it? 0.0

dull scarab
#

Logging is nice as we

#

Well

vestal apex
#

oh yeah you also need logging on

hollow tiger
#

logging? :o

vestal apex
#

the bullet point tells you the entirety of how to do it

hollow tiger
#

logging.basicConfig(level=logging.DEBUG)

#

basicConfig looks like js lmao

#

ohhh logging is a module?

dull scarab
#

Y

hollow tiger
#

so i just add ```py
logging.basicConfig(level=logging.DEBUG)

asyncio.get_event_loop().set_debug()```?

#

i can't restart my bot a lot because i'm actually supposed to be keeping it online for the servers

vestal apex
#

well try it with a test bot first

#

see if it works

hollow tiger
#

okay

#

oh my god

#

either i did this wrong

#

or my bot is working really hard

#

the console is literally being spammed

#
DEBUG:websockets.protocol:client < Frame(fin=True, opcode=2, data=b'\xc2\x17\xbd\xd4\xedm\x0e\xbd\xa5\x9d\xc0X1"\xa2\xf9E=\xab\x80q\x06\x00\x00\x00\xff\xff', rsv1=False, rsv2=False, rsv3=False)
DEBUG:discord.client:Dispatching event socket_raw_receive
DEBUG:discord.gateway:For Shard ID None: WebSocket Event: {'t': 'PRESENCE_UPDATE', 's': 73, 'op': 0, 'd': {'user': {'id': '424817451293736961'}, 'status': 'online', 'roles': ['484761158738247681', '458061225285386242'], 'nick': None, 'guild_id': '408397132165414924', 'game': {'type': 3, 'name': 'apps for 194178 users', 'id': 'ec0b28a579ecb4bd', 'created_at': 1536128388827}, 'activities': [{'type': 3, 'name': 'apps for 194178 users', 'id': 'ec0b28a579ecb4bd', 'created_at': 1536128388827}]}}
DEBUG:discord.client:Dispatching event socket_response
DEBUG:discord.client:Dispatching event member_update
DEBUG:asyncio:poll took 444.176 ms: 1 events
DEBUG:websockets.protocol:client < Frame(fin=True, opcode=2, data=b'\xc2\x17\x1fT>\xf3y\xe0\x1b\x00C5\x92\x00\x00\x00\x00\xff\xff', rsv1=False, rsv2=False, rsv3=False)
DEBUG:websockets.protocol:client < Frame(fin=True, opcode=2, data=b'\xc2\x17IT>\x99h0/\xed\x1c\x88\xa0\x07\x00\x00\x00\xff\xff', rsv1=False, rsv2=False, rsv3=False)
DEBUG:discord.client:Dispatching event socket_raw_receive
DEBUG:discord.gateway:For Shard ID None: WebSocket Event: {'t': 'PRESENCE_UPDATE', 's': 74, 'op': 0, 'd': {'user': {'id': '424817451293736961'}, 'status': 'online', 'roles': ['423378700881625088', '453724269990379531', '479369067090804736'], 'nick': None, 'guild_id': '423374132873527297', 'game': {'type': 3, 'name': 'apps for 194178 users', 'id': 'ec0b28a579ecb4bd', 'created_at': 1536128388827}, 'activities': [{'type': 3, 'name': 'apps for 194178 users', 'id': 'ec0b28a579ecb4bd', 'created_at': 1536128388827}]}}
DEBUG:discord.client:Dispatching event socket_response
DEBUG:discord.client:Dispatching event member_update
DEBUG:discord.client:Dispatching event socket_raw_receive```
#

this is only a tiny section

#

is that normal?

dull scarab
#

DEBUG:asyncio:poll took 444.176 ms: 1 events Believe you should be loking for these

hollow tiger
#

hmm...

#

DEBUG:asyncio:poll took 444.176 ms: 1 events

#

what's poll

#

i have no poll command

dull scarab
#

Is this part of start up, or constant run? ¯_(ツ)_/¯

hollow tiger
#

constant run

#
DEBUG:discord.client:Dispatching event socket_response
DEBUG:discord.client:Dispatching event member_update
DEBUG:asyncio:poll 280386.478 ms took 815.558 ms: 1 events
DEBUG:websockets.protocol:client < Frame(fin=True, opcode=2, data=b"\xc2\x1bF\xd4=\xd4\x88\xfe'T\x01\x00\x00\x00\xff\xff", rsv1=False, rsv2=False, rsv3=False)
DEBUG:discord.client:Dispatching event socket_raw_receive
DEBUG:discord.gateway:For Shard ID None: WebSocket Event: {'t': 'PRESENCE_UPDATE', 's': 134, 'op': 0, 'd': {'user': {'id': '424817451293736961'}, 'status': 'online', 'roles': ['484761158738247681', '458061225285386242'], 'nick': None, 'guild_id': '408397132165414924', 'game': None, 'activities': []}}
DEBUG:discord.client:Dispatching event socket_response
DEBUG:discord.client:Dispatching event member_update
DEBUG:asyncio:poll 279568.202 ms took 208.971 ms: 1 events
DEBUG:websockets.protocol:client < Frame(fin=True, opcode=2, data=b'\xc2\xeb9*w\xa9\x06\xc7\x11U\x00\x00\x00\x00\xff\xff', rsv1=False, rsv2=False, rsv3=False)
DEBUG:discord.client:Dispatching event socket_raw_receive
DEBUG:discord.gateway:For Shard ID None: WebSocket Event: {'t': 'PRESENCE_UPDATE', 's': 135, 'op': 0, 'd': {'user': {'id': '424817451293736961'}, 'status': 'online', 'roles': ['423378700881625088', '453724269990379531', '479369067090804736'], 'nick': None, 'guild_id': '423374132873527297', 'game': None, 'activities': []}}
DEBUG:discord.client:Dispatching event socket_response
DEBUG:discord.client:Dispatching event member_update
DEBUG:asyncio:poll 279356.369 ms took 110.922 ms: 1 events
DEBUG:websockets.protocol:client < Frame(fin=True, opcode=2, data=b'\xc2\xebc\xeavdhzF\x15\x00\x00\x00\xff\xff', rsv1=False, rsv2=False, rsv3=False)
DEBUG:discord.client:Dispatching event socket_raw_receive```
#

here's something else

#

DEBUG:asyncio:poll 279568.202 ms took 208.971 ms: 1 events

#

what is poll :thonk:

dull scarab
#

Could it be member_update?

#

What does your member update do?

hollow tiger
#

i don't have one

#

🤔

#

it does keep spamming member_update

dull scarab
#

Well, the event is triggered everytime a member changes anything about their profile

#

name, game, status etc

hollow tiger
#

i haven't ran the thing though

#

or

#

i don't have it

dull scarab
#

If you do anything about it is irrelevant for the event to trigger

#

But since youre not doing anything, it's probably not that

hollow tiger
#

still confused about DEBUG:asyncio:poll 279356.369 ms took 110.922 ms: 1 events

#

i'm searching everything and i don't see "poll" anywhere

dull scarab
#

But it does seem to be that on_member_update is the cause for that poll

#

¯_(ツ)_/¯

hollow tiger
#

i've searched every single cog confirming i don't have on_member_update

#

maybe it's the bot updating it's own presence?

#

since WebSocket Event: {'t': 'PRESENCE_UPDATE'

#

wait no - i cut that out

dull scarab
#

You could run a check and figure out whos id this is 424817451293736961

hollow tiger
#

it's my own bot

#

i just checked

#

but the bot literally isn't updating itself

dull scarab
#

Seems to be adding a role to itself?

#

Comparing these 2 ```py
{'t': 'PRESENCE_UPDATE', 's': 134, 'op': 0, 'd': {'user': {'id': '424817451293736961'}, 'status': 'online', 'roles': ['484761158738247681', '458061225285386242'], 'nick': None, 'guild_id': '408397132165414924', 'game': None, 'activities': []}}

{'t': 'PRESENCE_UPDATE', 's': 135, 'op': 0, 'd': {'user': {'id': '424817451293736961'}, 'status': 'online', 'roles': ['423378700881625088', '453724269990379531', '479369067090804736'], 'nick': None, 'guild_id': '423374132873527297', 'game': None, 'activities': []}}```

hollow tiger
#

guild id 408397132165414924

#

and guild id 423374132873527297

#

423374132873527297 is my own server

dull scarab
#

wait, yeah those are 2 different guilds

hollow tiger
#

423374132873527297 is my support server

#

and where i test everything

#

what's 408397132165414924 thonking

dull scarab
#

Try doing a bunch of commands

hollow tiger
#

uh

#

ok

#

it's gonna be a lot tho

#

just saying

dull scarab
#

¯_(ツ)_/¯

hollow tiger
dull scarab
#

Even after doing commands and such?

hollow tiger
#

well, i spammed one command

#

which i believe is most likely the cause

#

(may not be though)

#

this INFO:asyncio:poll 269400.905 ms took 1330.239 ms: 1 events is really bugging me

dull scarab
#
DEBUG:websockets.protocol:client < Frame(fin=True, opcode=2, data=b'"\xeck\xdcm\x1c\xe2}=\xd8\x16\x9b\x00\x00\x00\x00\xff\xff', rsv1=False, rsv2=False, rsv3=False)
DEBUG:discord.client:Dispatching event socket_raw_receive
DEBUG:discord.gateway:For Shard ID None: WebSocket Event: {'t': 'MESSAGE_REACTION_ADD', 's': 181, 'op': 0, 'd': {'user_id': '424817451293736961', 'message_id': '486789877833269258', 'emoji': {'name': 'yes', 'id': '426190071473897502', 'animated': False}, 'channel_id': '423383321788284928', 'guild_id': '423374132873527297'}}
DEBUG:discord.client:Dispatching event socket_response
DEBUG:discord.client:Dispatching event raw_reaction_add
DEBUG:discord.client:Dispatching event reaction_add
INFO:asyncio:poll 278239.561 ms took 3902.786 ms: 1 events```
#

Maybe try passing the logger to the bot, bot.log = logger

hollow tiger
#

like bot.log = logging.basicConfig(level=logging.DEBUG)?

dull scarab
#

and bog.log.debug(some detailed message about what its doing) in all of your commands

#

create the logger, then attach the instance to the bot

#

As this debug has information, but hard to tell where it's coming from

hollow tiger
#

uh

dull scarab
#
@commands.command()
async def my_cmd(ctx):
    bot.log.debug(f"{str(ctx.author)} called the command my_cmd in {ctx.guild} #{ctx.channel}")
    do stuff ...
    bot.log.debug(f"adding reaction 'someface' to {ctx.message.id} ")
    await ctx.message.add_reaction(someface)
    ...
    bot.log.debug("my_cmd finished running..")```
#

and so on

#

like a debug by every await to describe it

#

maybe a bit extreme for the final bot, but would help locating slow processes

hollow tiger
#

ook

dull scarab
#

Maybe just do one command at the time. Log it, and run it a few times in a row

hollow tiger
#
Traceback (most recent call last):

  File "/usr/local/lib/python3.6/dist-packages/discord/ext/commands/core.py", line 61, in wrapped
    ret = await coro(*args, **kwargs)

  File "/usr/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
    return self.gen.send(None)

  File "/home/joshuliu/AppBot/main/administrator.py", line 149, in configuration
    self.bot.log(f"Command {ctx.prefix}config was ran by {ctx.author.name} in #{ctx.channel.name} of {ctx.guild.name}.")

TypeError: log() missing 3 required positional arguments: 'data', 'action', and 'description'


The above exception was the direct cause of the following exception:


Traceback (most recent call last):

  File "/usr/local/lib/python3.6/dist-packages/discord/ext/commands/bot.py", line 898, in invoke
    await ctx.command.invoke(ctx)

  File "/usr/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
    return self.gen.send(None)

  File "/usr/local/lib/python3.6/dist-packages/discord/ext/commands/core.py", line 550, in invoke
    await injected(*ctx.args, **ctx.kwargs)

  File "/usr/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
    return self.gen.send(None)

  File "/usr/local/lib/python3.6/dist-packages/discord/ext/commands/core.py", line 70, in wrapped
    raise CommandInvokeError(e) from e

discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: log() missing 3 required positional arguments: 'data', 'action', and 'description'```
#

interesting

dull scarab
#

bot.log.debug

#

gotta say which type it is

hollow tiger
#

oh fuck

#

sry

#

like py self.bot.log.debug(f"Command {ctx.prefix}config was ran by {ctx.author.name} in #{ctx.channel.name} of {ctx.guild.name}.")?

#

i got py discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'function' object has no attribute 'debug'

dull scarab
#

howd you create your logger, and assign it

hollow tiger
#

bot.log = logging.basicConfig(level=logging.DEBUG)

#

am i wrong?

dull scarab
#
logger = logging.getLogger("discord")
# get event loop
# set_debug() on it

bot = discord.Bot...
bot.log = logger```
hollow tiger
#

uh

#

ok

#

but something dawned upon me

#

no matter how much these awaits and blocking functions happen, the json documents had the exact same asyncio functions, and was a lot faster than using databases

#

which was really ironic

dull scarab
#

The db is not blocking though

#

Json would be

hollow tiger
#

no but like

#

i used aiofiles

#

which asynchronously opened and saved files

#

Traceback (most recent call last):

  File "/usr/local/lib/python3.6/dist-packages/discord/ext/commands/core.py", line 61, in wrapped
    ret = await coro(*args, **kwargs)

  File "/usr/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
    return self.gen.send(None)

  File "/home/joshuliu/AppBot/main/administrator.py", line 149, in configuration
    self.bot.log.debug(f"Command {ctx.prefix}config was ran by {ctx.author.name} in #{ctx.channel.name} of {ctx.guild.name}.")

AttributeError: 'function' object has no attribute 'debug'


The above exception was the direct cause of the following exception:


Traceback (most recent call last):

  File "/usr/local/lib/python3.6/dist-packages/discord/ext/commands/bot.py", line 898, in invoke
    await ctx.command.invoke(ctx)

  File "/usr/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
    return self.gen.send(None)

  File "/usr/local/lib/python3.6/dist-packages/discord/ext/commands/core.py", line 550, in invoke
    await injected(*ctx.args, **ctx.kwargs)

  File "/usr/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
    return self.gen.send(None)

  File "/usr/local/lib/python3.6/dist-packages/discord/ext/commands/core.py", line 70, in wrapped
    raise CommandInvokeError(e) from e

discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'function' object has no attribute 'debug'```
dull scarab
#

What'dya write

hollow tiger
#

i got ```py
logger = logging.basicConfig(level=logging.DEBUG)

asyncio.get_event_loop().set_debug(True)

with open('prefixes.json') as file:
prefixes = json.load(file)
def customprefix(bot, message):
try:
prefixlist = prefixes[str(message.guild.id)]
if os.path.basename(file) == 'appbotdev.py':
prefixlist.append('.')
return commands.when_mentioned_or(*prefixlist)(bot,message)
except:
return '/'
bot = commands.Bot(command_prefix=customprefix,case_insensitive=True)
bot.remove_command('help')
bot.log = logger```

#

with open('prefixes.json') as file:
    prefixes = json.load(file)
def customprefix(bot, message):
    try:
        prefixlist = prefixes[str(message.guild.id)]
        if os.path.basename(__file__) == 'appbotdev.py': 
            prefixlist.append('.')
        return commands.when_mentioned_or(*prefixlist)(bot,message)
    except:
        return '/'
bot = commands.Bot(command_prefix=customprefix,case_insensitive=True)
bot.remove_command('help')``` is all irrelevant
dull scarab
#

thats not getLogger though

hollow tiger
#

i'm dumb

#

wait

#

wh

#

how does life work

#

logging.getLogger("asyncio")?

dull scarab
#

Try discord to begin with

hollow tiger
#

ok

dull scarab
#

may have to set its level to debug afterwards though

hollow tiger
#

so is it ```py
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger("discord")
asyncio.get_event_loop().set_debug(True)

#

oh

dull scarab
#
logger = logging.getLogger('discord')
logger.setLevel(logging.DEBUG)```
hollow tiger
#

okay

#

fUcUk

#

Traceback (most recent call last):

  File "/usr/local/lib/python3.6/dist-packages/discord/ext/commands/core.py", line 61, in wrapped
    ret = await coro(*args, **kwargs)

  File "/usr/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
    return self.gen.send(None)

  File "/home/joshuliu/AppBot/main/administrator.py", line 149, in configuration
    self.bot.log.debug(f"Command {ctx.prefix}config was ran by {ctx.author.name} in #{ctx.channel.name} of {ctx.guild.name}.")

AttributeError: 'function' object has no attribute 'debug'


The above exception was the direct cause of the following exception:


Traceback (most recent call last):

  File "/usr/local/lib/python3.6/dist-packages/discord/ext/commands/bot.py", line 898, in invoke
    await ctx.command.invoke(ctx)

  File "/usr/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
    return self.gen.send(None)

  File "/usr/local/lib/python3.6/dist-packages/discord/ext/commands/core.py", line 550, in invoke
    await injected(*ctx.args, **ctx.kwargs)

  File "/usr/lib/python3.6/asyncio/coroutines.py", line 110, in __next__
    return self.gen.send(None)

  File "/usr/local/lib/python3.6/dist-packages/discord/ext/commands/core.py", line 70, in wrapped
    raise CommandInvokeError(e) from e

discord.ext.commands.errors.CommandInvokeError: Command raised an exception: AttributeError: 'function' object has no attribute 'debug'```
#

logger = logging.getLogger("discord")
logger.setLevel(logging.DEBUG)
asyncio.get_event_loop().set_debug(True)

with open('prefixes.json') as file:
    prefixes = json.load(file)
def customprefix(bot, message):
    try:
        prefixlist = prefixes[str(message.guild.id)]
        if os.path.basename(__file__) == 'appbotdev.py': 
            prefixlist.append('.')
        return commands.when_mentioned_or(*prefixlist)(bot,message)
    except:
        return '/'
bot = commands.Bot(command_prefix=customprefix,case_insensitive=True)
bot.remove_command('help')
bot.log = logger```
dull scarab
#

Am i dum thinkies

#

2 sec

hollow tiger
#

okay

#

i gotta go when the time hits 30

#

i'm glad you've spent your time helping me out

#

thank you for the time

dull scarab
#

i may be missing something, but you could try setting up the recommended logger in the docs py logger = logging.getLogger('discord') logger.setLevel(logging.DEBUG) handler = logging.FileHandler(filename='discord.log', encoding='utf-8', mode='w') handler.setFormatter(logging.Formatter('%(asctime)s:%(levelname)s:%(name)s: %(message)s')) logger.addHandler(handler)

hollow tiger
#

a file?

dull scarab
#

It logs to a file then yeah

#

with that specific format

hollow tiger
#

uh

#

what if i don't want to have a file?

#

like only py logger = logging.getLogger('discord') logger.setLevel(logging.DEBUG)

dull scarab
#

just logging.Handler() then might do it

#

instead of FileHandler

hollow tiger
#

and ignore filename='discord.log', encoding='utf-8', mode='w'?

dull scarab
#

Yeah

hollow tiger
#

what's '%(asctime)s:%(levelname)s:%(name)s: %(message)s'?

dull scarab
#

The format for each debug line

#

it's time - level - name - and the error message you give it

#

so something like `23.04.2018-13:42.43434 DEBUG - discord : this message was logged

#

i believe

hollow tiger
#

asctime levelname name message?

#

ugh

#

same error

dull scarab
#

try a different variable name on the bot

#
logger = logging.getLogger('discord')
logger.setLevel(logging.INFO)
handler = logging.FileHandler(
    filename=f'logs/discord {datetime.datetime.today().strftime("%B %d, %Y")}.log', 
    encoding='utf-8', mode='a')
handler.setFormatter(logging.Formatter(
    '%(asctime)s:%(levelname)s:%(name)s: %(message)s'))
logger.addHandler(handler)

class MyBot(commands.Bot):
    def __init__(self, ...):
        ...
        self.logger = logger```
#

is what i do

#

self.bot.logger.debug("this went boo-boo") is how i use it, so why it wouldnt work is beyond me.

#

But then again, logging is one of the modules i learnt what I needed. not how it worked 😇

hollow tiger
#

damnit

dull scarab
#

Wish I could be of more help

hollow tiger
#

i have to go now - thank you for working with me tonight (in my timezone) towards fixing my problems

dull scarab
#

Bit of tweaking and testing and im sure you'll get it up and running

hollow tiger
#

yup

#

i was thinking though, since the json document saving had the same amount of asynchronous delay and blocking, how was it over two times faster than databases?

dull scarab
#

Inefficient use of the db module?

hollow tiger
#

that could be the source of the problem

#

are you on tomorrow around this time?

dull scarab
#

¯_(ツ)_/¯

ashen zenith
#

I know this is a Python server, but does anyone know much SQL? I'm struggling with a really basic question regarding joins

vestal apex
#

!t ask

delicate fieldBOT
#
ask

Asking good questions will yield a much higher chance of a quick response:

• Don't ask to ask your question, just go ahead and tell us your problem.
• Try to solve the problem on your own first, we're not going to write code for you.
• Show us the code you've tried and any errors or unexpected results it's giving
• Keep your patience while we're helping you.

You can find a much more detailed explanation on our website.

ashen zenith
#

This is the question. As I said, it's very basic, but I'm only learning and I'm struggling with joins. Any help appreciated 😃

vestal apex
#

what's your best guess so far?

ashen zenith
#

I'm thinking it's 3, but the answer (which could be wrong) is apparently 5

vestal apex
#

I think the trick is that it's a LEFT JOIN

ashen zenith
#

Which means Store1 + (Whatever Store1+2 share)

vestal apex
#

well the other thing is that you've got duplicate names there

ashen zenith
vestal apex
#

which I admit I am not familiar with the handling for. I haven't SQLed in a while

ashen zenith
#

Okay, no worries. Hopefully someone here can help haha. I appreciate it anyway

lucid pagoda
#

Any good tutorials for PostgreSQL? Gonna put something on Heroku at some point

vestal apex
#

ah, so the joining for duplicate names, @ashen zenith, looks like it matches up all the combinations py [(2, 'iPad', 1, 1000, 3, 'iPad', 900), (2, 'iPad', 1, 1000, 2, 'iPad', 1000), (3, 'iPad', 2, 1000, 3, 'iPad', 900), (3, 'iPad', 2, 1000, 2, 'iPad', 1000), (4, 'iPod', 6, 1000, 4, 'iPod', 400)]

full geyser
#

@ashen zenith you need to know how to do it for a test, or you wanna do it cuz u need it for a script?

#

cuz i needed to do it a while back, but it took way too long to do it in sql, so i wrote a python script to do it (had like 200k rows)

#

joins 2 tables to make a new table, using a shared column

#

the only negative is you need to have enough memory to store both tables (plus the new table)

patent glen
#

the only difference between left/right/inner/full join is what it does if there's no match.

#

left will omit rows if there's no matching row on the left, and use nulls if there's no matching row on the right, etc

#

er, omit if no matching row on the left for a given row on the right

#
(foo, bar) left join (foo, baz) -> (foo foo, bar null)
(foo, bar) right join (foo, baz) -> (foo foo, null baz)
(foo, bar) full join (foo, baz) -> (foo foo, bar null, null baz)
(foo, bar) inner join (foo, baz) -> (foo foo)```
full geyser
#

was it me doing something wrong that made it take forever, or are joins just a slow thing?

patent glen
#

nothing should be slow for only six rows, what exactly were you doing?

#

(joins in general can be fast or slow depending on indexes and execution strategy, but just three rows in each table should be fast even by brute force)

vestal apex
#

(200k rows)

full geyser
#

also my index was a 6-10 character utf8mb4 string 😂

#

but glad to know it wasnt just me doing something wrong

patent glen
#

you should have an index on the joined columns of at least one of the tables

#

preferably the one on the right in case of a left outer join, though both would be even better

slate bone
#
# To Check Member Clan
async def check_member_clan(member_id):
    loop = asyncio.get_event_loop()
    async with aiosqlite3.connect('clans.db', loop=loop) as conn:
        async with conn.cursor() as cursor:
            execution = await cursor.execute('SELECT clan_name FROM members WHERE id = (?)', (member_id,))
            clan_fetch = execution.fetchone()  # IT IS ('CLAN NAME',)
            return clan_fetch[0]  # THE ERROR IS HERE```
Shows that error .....
```Ignoring exception in on_ready
Traceback (most recent call last):
  File "C:\Users\User\AppData\Roaming\Python\Python36\site-packages\discord\client.py", line 220, in _run_event
    await coro(*args, **kwargs)
  File "ClansBot.py", line 20, in on_ready
    await clansbotconfig.check_member_clan(297493952674791425)
  File "C:\Users\User\Python Bots\clansbotconfig.py", line 109, in check_member_clan
    return clan_fetch[0]
TypeError: 'NoneType' object is not subscriptable```
#

@ me please

broken linden
#

well apparently the sql query didnt find db entries so it returned none as the first result leading to clan_fetch being None and if you then subscript clan_fetch with [0] the error you get comes out

#

@slate bone

slate bone
#

Oooo I figured it that error shows when the member is removed that's why it was working while ago

#

Thanks

hollow tiger
#

wait

#

does db.get(str(ctx.guild.id))["apps"]["Moderator"]["app"].run(conn) read the whole document and then access nested fields, or only read the specified nested field?

vestal apex
#

I would assume the latter, given the location of the square brackets

hollow tiger
#

hmm... that might also be why my bot is slower

#

because currently i haven't made any major changes yet - the bot still does read the entire document

vestal apex
#

"the latter" meaning the second one

#

so not the whole document

hollow tiger
#

i know

#

i diidn't put db.get(str(ctx.guild.id))["apps"]["Moderator"]["app"].run(conn), i just planned to

vestal apex
#

ah

hollow tiger
#

how would i rename a key of a document in rethinkdb?
e.g. make {"hi:"bye"} to {"hello":"bye"}

vestal apex
#

that seems like a matter of grabbing the value, deleting the key, and creating a new one

#

renaming a key is not a concept frequently addressed in any situation because ideally your keys are relatively stable

hollow tiger
#

I see

#

so i'd duplicate it with the new name, and delete the old one?

vestal apex
#

that would be my first instinct, assuming you haven't found anything relevant in the docs

hollow tiger
#

yea, i didn't find anything

#

ok

#

thank you

terse stump
#

so i need some help and instead of finding the answer myself, maybe it is faster to ask here 😄 using sqlalchemy I would like to call a stored procedure from a microsoft sql server. is there a way of doing it directly of do i have to call the underlying cursor, like you would normally do with pyodbc?

honest jolt
#
avg = [[row[1].value] for row in sheet if row[0].value.MAXYEAR == 2000]```
#

I'm trying to get data points in a excel file between 1900-2000 in years, whats the command i need to use?

patent glen
#

@honest jolt something like if 1900 <= (however you can get the year - what type is row[0].value?]) <= 2000

#

what library are you using to read the excel sheet, do the dates come back as datetime objects, strings, numbers, or something else?

#

also maybe consider using pandas

honest jolt
#

@patent glen Im using openpyxl to open and read the excel sheet

patent glen
#

ok assuming it's a datetime object

#

do like ...if 1900 <= row[0].value.year <= 2000...

honest jolt
#
import sqlite3
import matplotlib.pyplot as plt
import openpyxl as ol

wb = ol.load_workbook("ClimateData.xlsx")
sheet = wb.get_sheet_by_name('Sheet1')

avg = [[row[1].value] for row in sheet if 1900 <= row[0].value.year <= 2000]```
#

anybody know how to skip the first row on the excel document

patent glen
#

for row in sheet[1:]

#

maybe

#

i'm not 100% sure about openpyxl

honest jolt
#

IndexError: slice(1, None, None) is not a valid coordinate or range

#

😦

#

yea I have t ouse openpyxl for this task

patent glen
#

for row in sheet.iter_rows(min_row=2)

honest jolt
#

AttributeError: 'str' object has no attribute 'year'

#

still reading header

patent glen
#

ok maybe turn this into a loop and print your stuff so you can see better what's going on

#

like py avg = [] for row in sheet.iter_rows(min_row=2): print(row[0].value) if 1900 <= row[0].value.year <= 2000: print(row[1].value) avg.append([row[1].value])

honest jolt
#

im experimenting with this now python for row in range(1, n.rows(sheet)):

#

it prints the time stamps

patent glen
#

what format

#

print(repr(row[0].value))

honest jolt
#

2013-07-01 00:00:00

patent glen
#

and do you still get the error or not

honest jolt
#

datetime.datetime

#

well it works however it does graph my data

#

which defeats the purpose of this task

dull scarab
#

Following the form of sql UPDATE users SET karma = karma + $1 WHERE id = $2 AND guild_id = $3
Is it possible to make sure karma does not go below a specific negative value here?

ionic pecan
#

use a check constraint

dull scarab
#

Is that only limited to creating the fields, or can i use it in a query

#

Oh well, I couldn't find any way to use it with queries, guess ill just rewrite the table constructor

hazy peak
#

Hello, I want to UPDATE my table
users(cheer(int), exp(int))
cheer column according to column exp value. Example
if 0<exp<10, update cheer = cheer +1, elif 10<=exp < 20, update cheer = cheer + 2.
What is best way to update all of rows? Is it possible to do it with sql syntax?

ionic pecan
#

generally you can do any kind of data manipulation in SQL, because that's what it was made for..

#

for your question, look at CASE

torn sphinx
#
@client.command(pass_context=True)
async def leaderboard(ctx):
    res1 = c.execute("SELECT Coins FROM Users ORDER BY Coins DESC;")
    res1 = res1.fetchone()
    embed = discord.Embed(title="Most coins", description="The top users with the most Coins", color=0xfffafa)
    res2 = c.execute("SELECT UserID FROM Users ORDER BY Coins DESC;")
    res2 = res2.fetchone()
    for counter in range(0, 1):
        for member in ctx.message.server.members:
            counter_id = str(res2[counter])
            if counter_id == member.id:
                print(str(res1[counter]))
                embed.add_field(name=member.display_name, value=str(res1[counter]), inline=False)
                break
    await client.say(embed=embed)

#

I tried changing the loop

#

for counter in range(0, 1):

hazy peak
#

I could use with the value of the data in my table right?

torn sphinx
#

from 1 to 2

ionic pecan
#

"the value of the data in my table" is somewhat unspecific, if you mean "a column", then yes

torn sphinx
#

😐

hazy peak
#

yes, column data

ionic pecan
#

yeah

hazy peak
#

I'll take a look at the case condition

torn sphinx
#
Ignoring exception in command leaderboard
Traceback (most recent call last):
  File "C:\Users\BODZIO\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 50, in wrapped
    ret = yield from coro(*args, **kwargs)
  File "C:\Users\BODZIO\Desktop\Discord Bot\DiscordBot.py", line 198, in leaderboard
    counter_id = str(res2[counter])
IndexError: tuple index out of range

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\BODZIO\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\bot.py", line 846, in process_commands
    yield from command.invoke(ctx)
  File "C:\Users\BODZIO\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 374, in invoke
    yield from injected(*ctx.args, **ctx.kwargs)
  File "C:\Users\BODZIO\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 54, in wrapped
    raise CommandInvokeError(e) from e
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: IndexError: tuple index out of range

hazy peak
#

but do I need to use SELECT to get the data first?

ionic pecan
#

don't think so

#

check out the exact UPDATE syntax

#

@torn sphinx if you're working with a discord bot then that error's description should tell you enough to solve the issue on your own

#

you select a single column and try to access the result tuple at index 1

torn sphinx
#

But I have been trying for weeks

hazy peak
#

I'll look into it. thks for the tip 😉

torn sphinx
#

I will try do it 😐

ionic pecan
#

i mean, I just told you why that error is happening

hazy peak
#

why use "for" for range(0, 1), that is just 1 iteration

#

nvm

torn sphinx
#

that will just give you a syntax low

hazy peak
#

I believe you could just remove that "for counter in range(0, 1):" and instead counter use 0

dull scarab
#

For x in range(0, 1) will indeed only iterate once, with the value 0

#

If thats the topic here

hazy peak
#

yea, it is always 0

devout oasis
#

Okay this might be a dumb question but how do i use MongoDB? is there a special documentation? and how do i make a database with it?

hollow tiger
devout oasis
#

thank you so much

hollow tiger
#

lol np

hazy peak
#

Hey there, I am updating mysql table with only (user_id, product_id). Does mysql stores the date/time of that log or should I add another column like (user_id, product_id, date_time) ?

#

And also store date_time of that log?

dull scarab
#

You could specify a timestamp column, and have it default to CURRENT_TIMESTAMP

#

Or add it yourself

#

but you need a column for it, afaik

hazy peak
#

Thks man.

snow slate
#

hey everyone
I am having problem connecting vs code extension mssql to the server

if anyone can help me out
i would really appreciate your efforts

viral crag
#

Looks like your connection details are incorrect, or the server isn't running.

hazy crystal
#

Guys is there a way to make multiprocessing write to db one process at a time. I tried with Lock() but it failed me

rancid pier
#

again, what DB

#

it's basically question number 0 when you want to know how to do X on a db

#

what DB

hazy crystal
#

let me check

#

i mean its mysql dunno the db engine

rancid pier
#

so it's mysql 😅

hazy crystal
#

the problem is that I have a script which download lots of file and maps them to the db like this. It gets the records from db. Download the urls then md5 hash the url into a filename for example, xxxxx.jpg (hash of url) then it updates the db records

hazy crystal
#

the problem is that I can't update while running the script since it uses multiprocessing and somehow it doesn't work with Lock()

rancid pier
#

are you using multiprocessing or multiprocessing.dummy?

hazy crystal
#

multiprocessing

#

the way i implemented it is

#

take the urls, split it into x part (10 for example). Make 10 process and download the page then (i was planning to update the db every 1000 K urls but it crashed)

#

Was using Lock.acquire and lock.release when trying to run the db

rancid pier
#

what do you mean run the db

#

to do the insert update operation?

hazy crystal
#

to do the update operation

rancid pier
#

why do you need to lock? cause different processes might try to update the same record?

hazy crystal
#

no they wouldn't

rancid pier
#

then if you're sure of that you don't even need a lock

hazy crystal
#

they can only update 1 records and its unique

rancid pier
#

wait what

hazy crystal
#

i mean the 1000K urls have unique records so they can't interfere with each other

#

but i though that if a process was writting to db the other can't access it

rancid pier
#

databases are perfectly capable of handling concurrent reads and writes, what you have to worry about is collision

hazy crystal
#

ok im gonna try this

rancid pier
#

but

#

make sure your tables are InnoDB

#

old-style MyISAM tables lock the entire table for a write operation, while (iirc) InnoDB locks the specific row, based on indices

#

if you can reduce your update to a single statement, mysql engine implicit locking is sufficient @hazy crystal

#

if your writes are slow asf you might be dealing with a MyISAM table

hazy crystal
#

I'm using executmany so its probably a single statment

rancid pier
#

not sure you can do that with execute many

#

unless you use insert with the ON DUPLICATE KEY clause I mentioned earlier

#

but in your case if it's a proper InnoDB table, even dumping a stream of single UPDATEs should be fast enough for an amount of records as tiny as 10k rows

dusky owl
#

How do I setup different tables in mongo? Like if I have a db called "accounts" and I want a field for like user, password, id, and role?

dull scarab
#

Just quoting this from earlier, can't confirm

dusky owl
#

Trying to read the docs but it's kind of hard to parse everything, like is a collection the name of a table?

dull scarab
dusky owl
#

This is pretty annoying to setup I just want to make 4 tables. Does that exist in mongo?

#

Is there an auto increment column?

ionic pecan
#

are you reinventing sql in nosql?

dusky owl
#

I guess so, not intentionally. Just using Mongo for a thing and wanting To know if there's similar functionality between the two

#

To mess with it, so I dind't know if it was something I was missing or something that's just actually not supported

quasi dew
broken linden
#

you could use beautiful soup 4 to scrape the website, although the conjugation is always presented as picture so you willl hardly get data out of it.

quasi dew
broken linden
#

once you got a list of verbs you can do that i guess

quasi dew
#

is it publicly accessible at Verbix, do u have any idea?

broken linden
#

i dont know im not into this at all

#

i just know how to get structured info out of html sites with python

quasi dew
#

thanks for all your help. : )

dull scarab
#

How would I sum values from TableA with a common column value, and reference the sum in TableB
eg. I have a user table, which has a column total_invite
an invites table sql CREATE TABLE IF NOT EXISTS invites( hash text PRIMARY KEY, count int default 0 ); and a relation table between them, sql CREATE TABLE IF NOT EXISTS userToInvite( user_id bigint NOT NULL, invite_hash text NOT NULL ); and want the total_invite count to be the sum of all invites count rows with that users id

#

Or would I just have to query all the matching invites, sum em manually and update user

ionic pecan
#

If your user to invite table has a foreign key to the user table, why not just issue a select and join?

#

also, can one invite be owned by many users?

dull scarab
#

No

#

One user to many invites

#
CREATE TABLE IF NOT EXISTS users(
    id bigint NOT NULL,
    guild_id bigint NOT NULL,
    karma int default 0,
    points int default 0,
    total_invites int default 0,
    invited_on timestamp NOT NULL,
    CHECK (karma > -100),
    CHECK (points > -1),
    PRIMARY KEY(id, guild_id)
    );```
#

This is slightly outside my comfort zone for sql, so also wondering if this is the correct way to fetch all invites, with their corresponding user.id sql SELECT users.id, invites.hash, invites.counter FROM users LEFT JOIN userToInvite uTI ON uTI.user_id = users.id LEFT JOIN invites ON uTI.invite_hash = invites.hash;

ionic pecan
#

Why the junction table if it‘s one to many?

dull scarab
#

Uuuh

#

i~

#

yes.

#
CREATE TABLE IF NOT EXISTS invites(
    inv_hash text,
    creator_id bigint,
    counter int default 0,
    PRIMARY KEY(inv_hash, creator_id)
);``` Something like this then?
ionic pecan
#

The creator would be a user?

dull scarab
#

Yeah

ionic pecan
#

Apart from adding a foreign key, sure

dull scarab
#

I don't know of the correct way to create relational tables

torn sphinx
#

and the bad order in that key

ionic pecan
#

You‘re using Postgres I assume?

dull scarab
#

Yup

dull scarab
#

So invites would reference a user, while a users total_count would be the sum of all invites referencing hims counter

#

if that makes sense

#

So i'd only have to update the counter on individual invites, without having to update the relevant user as well

#

But lemme give that a read rqw

ionic pecan
#

I don‘t think you should have that total counter field, just run a select count on the invites table

dull scarab
#

Hm

#

Fair enough

ionic pecan
#

If you really wanted I guess you could use a view

dull scarab
#

Nah, you're right

#

I should just query the invites now

#

Makes more sense with the new setup

#

Not having the tables setup yet to test it, but would this be the equivalent of querying the db to check if an invite exists before inserting or updating?

INSERT INTO invites (inv_hash, creator_id, counter)
    VALUES ($1, $2, $3)
    ON CONFLICT (inv_hash) DO UPDATE SET counter = $3```
ionic pecan
#

Looks like it, yes

dull scarab
#

👌

#

Thanks

hollow tiger
#

So over the past days, i've been working on fixing up the speed of my Discord Bot, and one of the big things that i've done was change the bot's way of saving data from separate per-server json documents in a folder to one big database which saves data. For whatever reason, the bot's response time has nearly doubled after I started using databases. I haven't changed anything else (including other asyncio events) - only json documents to databases, meaning there's something about databases slowing my bot down. Does anyone know what could be the issue here? I am using RethinkDB. (Those of you who've helped me on this already know what i'm talking about)

full geyser
#

why would you save a json document to a database tho? doesnt that kind of defeat the whole point of having a database if you just save the file?

#

also idk about rethingDB but i tested mysqldb vs json, and json was faster as longas the file was quite small

#

as soon as the amount of data i had to store got big, mysql won

#

by big, i mean like either 100 or 1000 rows with like 10 columns (or dictionaries with items)

ionic pecan
#

MySQL is a text file on drugs

Reading JSON files directly might be faster than using something like postgres because it‘s direct file access but thats just about the only advantage i can think of

deft badge
#

Postgres JSONB fields hyperlemon

#

you will get slightly lower read times with JSON because you are working with not only disk access, but a disk cache, so the file is stored in flash memory anyway and is easier to retrieve and write to

#

Well, not easier, but quicker

ionic pecan
#

yeah that‘s just about all advantages though

#

no defined schema, no query language, just dumb „find the next thing in this list with is = 5“ operations, no constraints

#

you cant just go and tell json to build you a btree of user ids so you can look something up quickly

#

There‘s also no relationships

deft badge
#

Yeah, in the long run, a big dictionary isn't going to solve your needs for any large scale software

#

As you said btrees, relationships, constraints, a schema and a query language are crucial things for a fast application

ionic pecan
#

and those are just scratching the surface

upbeat rivet
#

Can'T you make a dict with postgresql like that:

    await client.c.execute(
        "INSERT INTO economy VALUES (:ID, :Name, :Cash, :Bank, :Getreide, :Kupfer, :Holz, :Drogen, :Waffen, :Diamant) ON CONFLICT(ID) DO NOTHING",
        {'ID': str(ctx.author.id), 'Name': str(ctx.author.name), 'Cash': 0, 'Bank': 5000, 'Getreide': 0,
         'Kupfer': 0, 'Holz': 0, 'Drogen': 0, 'Waffen': 0, 'Diamant': 0})```
marsh knot
#

I want to be able to track when data changes, how would I do that in a database sense?

#

I was thinking having all entities with a datetime attribute, but ehh...

torn sphinx
#

Hey guys

ionic pecan
#

@upbeat rivet what exactly are you asking?

#

@marsh knot like an "updated at" attribute?

#

@torn sphinx hello there. if you're looking for casual conversation, check out our off-topic channels

marsh knot
#

I'll wait my turn lol

ionic pecan
#

just ask

#

i can multitask hyperlemon

torn sphinx
#

Volcy i actually had code that i deleted

marsh knot
#

pfff haha

torn sphinx
#
import sqlite3
import discord
import time
import datetime
import random

from discord.ext import commands

conn = sqlite3.connect("database.db")
c = conn.cursor()

c.execute("CREATE TABLE IF NOT EXISTS bank(User_ID INT PRIMARY KEY NOT NULL, Balance float)")


class BankInfo():
    conn = sqlite3.connect("database.db")
    c = conn.cursor()

    def __init__(self, bot):
        self.bot = bot

    @commands.command()
    async def register(self,ctx):
        c.execute("INSERT INTO bank VALUES (?, ?)", (ctx.author.id, 0))
        conn.commit()

    @commands.command()
    async def work(self,ctx):
        c.execute("UPDATE TABLE bank SET balance=balance+? WHERE user_id=?", (random.randint(69, 1337), ctx.author.id))
        conn.commit()

def setup(bot):
    bot.add_cog(BankInfo(bot))
    conn = sqlite3.connect("database.db")
    c = conn.cursor()
marsh knot
#

woah

torn sphinx
#

So i have this

marsh knot
#

yeah I'll wait, Volcyy ;P

torn sphinx
#

However my register command wont upload to my table

upbeat rivet
#

Nm that Question I have an other one. So can I do something like: fetchone(SELECT) which only returns one variable I want to get.

Since like if I do:var = ..fetch(SELECT...)

And print var it will not give me only one var.
I need to do: var[0]

torn sphinx
#

did you try fetchall

upbeat rivet
#

Btw. I am using asynpg

torn sphinx
#

oh

upbeat rivet
#

Fetchone is not a thing there

ionic pecan
#

you will always get an iterable of tuples

torn sphinx
#

im next volcyy unless fire is

upbeat rivet
#

So there is no way to make it only one word. Since I used sqlite before and I could just do.fetchone()

ionic pecan
#

"only one word"?

#

I mean you could use tuple unpacking

#
(name,) = cursor.fetchone()
upbeat rivet
#

I did that to unpack it

ionic pecan
#

@torn sphinx what does "upload to my table" mean?

torn sphinx
#

so im using sqlite

upbeat rivet
#

But still it will give me something like: <Table Content: 'var'>

torn sphinx
#

and im trying to make a bank and a way to work

upbeat rivet
#

If I just print var.

torn sphinx
#

however my register command wont add a new row to my table for the person that registered

ionic pecan
#

what are you storing in your database that returns an object like that?

#

are you checking the correct table?

#

do you have something gobbling up a potential error?

torn sphinx
#

no errors is the problem

#
import sqlite3
import discord
import time
import datetime
import random

from discord.ext import commands

conn = sqlite3.connect("database.db")
c = conn.cursor()

c.execute("CREATE TABLE IF NOT EXISTS bank(User_ID INT PRIMARY KEY NOT NULL, Balance float)")


class BankInfo():
    conn = sqlite3.connect("database.db")
    c = conn.cursor()

    def __init__(self, bot):
        self.bot = bot

    @commands.command()
    async def register(self,ctx):
        c.execute("INSERT INTO bank VALUES (?, ?)", (ctx.author.id, 0))
        conn.commit()

    @commands.command()
    async def work(self,ctx):
        c.execute("UPDATE TABLE bank SET balance=balance+? WHERE user_id=?", (random.randint(69, 1337), ctx.author.id))
        conn.commit()

def setup(bot):
    bot.add_cog(BankInfo(bot))
    conn = sqlite3.connect("database.db")
    c = conn.cursor()

This is my command

pseudo compass
#

uhm

#

lmao you have 3 cursors

#

it won't like that

torn sphinx
#

Now there is one

pseudo compass
#

you're making 3 separate connections and 3 separate cursors, sqlite won't like that

ionic pecan
#

ah yeah, you might have a lock or something like that

#

@marsh knot ask!

marsh knot
#

aRGH OK

#

So like, something that tracks changes eg:

26 +++ "name": "bar"```
#

I can just use difflib for text, but for a database, eh..

ionic pecan
#

what is your database?

torn sphinx
#

How do i unlock my database?

marsh knot
#

actually sorry I gtg

#

timezones™

torn sphinx
#
import sqlite3
import discord
import time
import datetime
import random

from discord.ext import commands

conn = sqlite3.connect("database.db")
c = conn.cursor()

c.execute("CREATE TABLE IF NOT EXISTS bank(User_ID INT NOT NULL UNIQUE, Balance float)")


class BankInfo():
    def __init__(self, bot):
        self.bot = bot

    @commands.command()
    async def register(self,ctx):
        c.execute("INSERT INTO bank VALUES (?, ?)", (ctx.author.id, 0))
        conn.commit()

    @commands.command()
    async def work(self,ctx):
        c.execute("UPDATE TABLE bank SET balance=balance+? WHERE user_id=?", (random.randint(69, 1337), ctx.author.id))
        conn.commit()

def setup(bot):
    bot.add_cog(BankInfo(bot))




#

This is what it looks like now

pseudo compass
#

and it doesn't work?

torn sphinx
#

Nope

pseudo compass
#

what doesn't work, exactly? what are you expecting to happen?

torn sphinx
#

So on register i want to if not already in system create a user account using their ctx.author.id and set the balance to 0

#

Then on the work command i want it to update their own bank account with x amount of money which is rand

pseudo compass
#

@torn sphinx I'd change your User_ID field to BIGINT, because discord ids are large enough it will either cause an error or unexpected behavior

#

@torn sphinx I don't believe sqlite allows to update values inplace, like you're trying to do with balance. You need to first get the balance from the database, then update it with the new value

torn sphinx
#

So how would i do that

pseudo compass
#

just add a query to select the users's balance

torn sphinx
#

idk how

pseudo compass
#

its just a sql select query

torn sphinx
#

data = SELECT Balance FROM bank

#

?

pseudo compass
#

kinda

torn sphinx
#

Wait i cant even get my register to work

pseudo compass
#

im somewhat amazed you wrote an update query without understanding a select query

torn sphinx
#

really?

pseudo compass
#

yea, select is pretty basic sql

#

anyway, change your id datatype and fix your update command and you should be good

#

may wanna commit after you make the table tho

torn sphinx
#

Can you help me a bit more?

pseudo compass
#

i dont see how i could help you anymore besides spoonfeeding you code, and that doesn't help anyone

torn sphinx
#

It helps me lmao because templates always help

#
@bot.command()
async def register(ctx):
    c.execute("INSERT INTO bank VALUES(?, ?),(ctx.author.id, 0)")

#

Anyways i meant help with this

#

it isnt inserting into bank

pseudo compass
#

probably because you havent committed your create table statement, or because your datatype on user_id is wrong

delicate fieldBOT
#

Hey @torn sphinx! I noticed you posted a seemingly valid Discord API token in your message and have removed your message to prevent abuse. We recommend regenerating your token regardless, which you can do here: https://discordapp.com/developers/applications/me
Feel free to re-post it with the token removed. If you believe this was a mistake, please let us know!

torn sphinx
#
import sqlite3
import discord
import time
import datetime
import random

from discord.ext import commands

bot = commands.Bot(command_prefix='a!')

conn = sqlite3.connect("database.db")
c = conn.cursor()

c.execute("CREATE TABLE IF NOT EXISTS bank(User_ID BIGINT NOT NULL, Balance float)")
conn.commit()

@bot.event
async def on_command_completion(ctx):
    await ctx.message.delete()

@bot.command()
async def register(ctx):
    c.execute("INSERT INTO bank VALUES(?, ?),(ctx.author.id, 0)")

@bot.command()
async def work(ctx):
    data = c.execute("SELECT Balance FROM bank")
    print(data)
    c.execute("UPDATE TABLE bank SET balance=balance+? WHERE user_id=?", (random.randint(69, 1337), ctx.author.id))

@bot.event
async def on_ready():
    print(f"Logged in as {bot.user.name}")
    print(f"ID : {bot.user.id}")
    print(f"Preparing Game")
    game = discord.Game(" Nothing | Guild Count: 3")
    await bot.change_presence(status=discord.Status.online,activity=game)
    print(f"Playing {game}")

pseudo compass
#

Oh i see. your data tuple shouldnt be part of your insert query. c.execute takes two args, the query and the tuple of values

#

your select query oughta have a check to make sure you get the balance for the right user, and you need to pass that data in your update query because field=field+N is not valid in sqlite

torn sphinx
#

so what do i put?

upbeat rivet
#

@ionic pecan sorry.. I had it a bit wrong..
When I type:

economy, = await client.c.fetch("SELECT name FROM economy WHERE ID = $1", ctx.author.id)
print(economy)```
I get:

```py
<Record name='Squanchy'>```

If I print:
```py
print(economy[0])```

I get:
```py
Squanchy```

But can't I make it without [0] ?
torn sphinx
#

Anon

pseudo compass
#

@torn sphinx I suggest you do some research on SQL syntax

torn sphinx
#

It keeps locking my database

#

it worked then locked my database

pseudo compass
#

you should commit everytime you change the database

upbeat rivet
#

As well as if I have something like: <Record id= '178244481668218885' name='Squanchy'>

That I can print the name without doing print(economy[1]) with something like print(economy.name) ?

torn sphinx
#

I do commit

#

but now the database is locked

#

Ok fixed it

#

now i dont want multiple people creating the same user

#

wait they cant anyways

pseudo compass
#

@upbeat rivet what exactly are you wanting?

upbeat rivet
#

Do you know what I mean ? :D

#

Okay wait..

#

This:

economy, = await client.c.fetch("SELECT name FROM economy WHERE ID = $1", ctx.author.id)``` gives me: 
```py
<Record name='Squanchy'>```
if I print it..
#

But I only want to print Squanchy

#

not <Record name='Squanchy'>

#

I can do that by doing:
print(economy[0])
But isn't there an other way?
Like print(ecobonmy.name)

#

Or even an different fetch type like for SQLite .fetchone()

pseudo compass
#

i dont have any idea what library you are using

upbeat rivet
#

Asyncpg

pseudo compass
#

can you not test it?

upbeat rivet
torn sphinx
#

Anon

upbeat rivet
#

I just found out that I can use fetchval.

torn sphinx
#

Now how do i list the balance for the user

pseudo compass
#

@torn sphinx Like I said, I suggest you do some research on SQL syntax. It's gonna make this a lot easier if you know sql basics

upbeat rivet
#

You can get the balance by the SELECT query Where ID = ctx.author.id for example

#

Anyways...
@pseudo compass do you know how I can get for the outcome:

<Record id='178244481668218885'  name='Squanchy'>```to print the name for example :D ? Like it looks like it is meant to get certain content if it is listed like that
torn sphinx
#

so i have this

#

c.execute("SELECT Balance FROM bank WHERE User_ID = ?",(ctx.author.id))

#

but this returns the object

upbeat rivet
#
balance, = c.execute("SELECT Balance FROM bank WHERE User_ID = ?",(ctx.author.id)).fetchone()```

print(balance)
pseudo compass
#

@upbeat rivet looks like you can just print the attribute

#

but i dont use asyncpg, so im not sure

torn sphinx
#

and now how would i send the top 10 balances?

upbeat rivet
#

You need to make an for loop

#

and sort by balance

pseudo compass
#

no

#

You can use raw sql for this

#

just an order by clause

upbeat rivet
#

But to show the rank you need a for loop and count the places I guess

torn sphinx
#

i only wanna show top 10 tho

upbeat rivet
#

Then make a LIMIT 10

torn sphinx
#
 File "C:\Users\skinn\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 61, in wrapped
    ret = await coro(*args, **kwargs)
  File "C:\Users\skinn\Desktop\Alchemist\cogs\database.py", line 35, in balance
    Balance = c.execute("SELECT Balance FROM bank WHERE User_ID = ?",(ctx.author.id))
ValueError: parameters are of unsupported type

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\skinn\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\bot.py", line 898, in invoke
    await ctx.command.invoke(ctx)
  File "C:\Users\skinn\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 550, in invoke
    await injected(*ctx.args, **ctx.kwargs)
  File "C:\Users\skinn\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 70, in wrapped
    raise CommandInvokeError(e) from e
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: ValueError: parameters are of unsupported type
#

This is on the balance command

pseudo compass
#

-- nvm

#

rn the brackets aren't doing anything

#

(5) -> int
(5,) -> tuple

torn sphinx
#

<sqlite3.Cursor object at 0x041774E0>

upbeat rivet
#

Send the command

#

What u are actually using now

torn sphinx
#

this is what it sends now

#

it sends the object instead of the balance'

upbeat rivet
#

.fetchone()

#

U are using sqlite right?

torn sphinx
#

yes

#

again returned the object

#

now it sends this in error

#
Ignoring exception in command balance:
Traceback (most recent call last):
  File "C:\Users\skinn\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 61, in wrapped
    ret = await coro(*args, **kwargs)
  File "C:\Users\skinn\Desktop\Alchemist\cogs\database.py", line 36, in balance
    await ctx.send(Balance)
  File "C:\Users\skinn\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\abc.py", line 761, in send
    data = await state.http.send_message(channel.id, content, tts=tts, embed=embed, nonce=nonce)
  File "C:\Users\skinn\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\http.py", line 213, in request
    raise HTTPException(r, data)
discord.errors.HTTPException: BAD REQUEST (status code: 400): Cannot send an empty message

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\skinn\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\bot.py", line 898, in invoke
    await ctx.command.invoke(ctx)
  File "C:\Users\skinn\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 550, in invoke
    await injected(*ctx.args, **ctx.kwargs)
  File "C:\Users\skinn\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 70, in wrapped
    raise CommandInvokeError(e) from e
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: HTTPException: BAD REQUEST (status code: 400): Cannot send an empty message

pseudo compass
#

@torn sphinx you may want to read the error

gusty spindle
#

yeah, reading errors is a good idea.

torn sphinx
#

fetchone() made it no message

gusty spindle
#

so then check before you send it?

#

:D

torn sphinx
#

and no fetchone() makes it an object

gusty spindle
#

could you show us some code then?

torn sphinx
#
    @commands.command()
    async def balance(self,ctx):
        Balance = c.execute("SELECT Balance FROM bank WHERE User_ID = ?",(ctx.author.id,)).fetchone()
        await ctx.send(Balance)
#

i deleted fetchone'

#

There is some code

dull scarab
#

Check if balance get's a result before sending

torn sphinx
#

it gets the object

dull scarab
#

what is the object and how do you know

torn sphinx
#

because it prints the object

dull scarab
#

What is the object then?

torn sphinx
#

<sqlite3.Cursor object at 0x041774E0>

dull scarab
#

You'd need to fetch the response

torn sphinx
#

so .fetchall()

dull scarab
#

or fetchone

torn sphinx
#

fetchone returned no message

dull scarab
#

Then your query didn't find any match

#

Hence why you'd check if you found something, before sending

torn sphinx
#

how

#

anon i broke it again

#

not registering and not sending error

#

fixed it

#

Floppy how do i "check"

dull scarab
#

if Balance: do stuff

torn sphinx
#

...

dull scarab
#

What? That is legit all you need

torn sphinx
#

if Balance:
Do what

dull scarab
#

Send Balance?

#

That's what you're trying to do, is it not

torn sphinx
#

so if Balance:
await ctx.send(Balance)

#

It works

#

Now what about having a leaderboard for top 10

#

however how do i make the balance an int instead of a list

#

Because in order to make my work command add to Balance, it must be something besides list

#

anyone?

#

ok

#

I am making a Leaderboard command

#

well it is made

#

But the thing is it only shows one person

#

Can i see it?

#

ok

#
@client.command(pass_context=True)
async def leaderboard(ctx):
    res1 = c.execute("SELECT Coins FROM Users ORDER BY Coins DESC;")
    res1 = res1.fetchone()
    embed = discord.Embed(title="Most coins", description="The top users with the most Coins", color=0xfffafa)
    res2 = c.execute("SELECT UserID FROM Users ORDER BY Coins DESC;")
    res2 = res2.fetchone()
    for counter in range(0, 1):
        for member in ctx.message.server.members:
            counter_id = str(res2[counter])
            if counter_id == member.id:
                print(str(res1[counter]))
                embed.add_field(name=member.display_name, value=str(res1[counter]), inline=False)
                break
    await client.say(embed=embed)
#

did you try using top?

#

top?

#

SELECT TOP 10 column-name
FROM table_name
[where condition];

#

no

#

for counter in range(0, 1):

#

That is one

#

when I put 2 that are in the database

#

it gives error

#

did you try 1, 3

#

waot

#

if it errors

#

whats the error

#

I give you

#

one sec

#
Ignoring exception in command leaderboard
Traceback (most recent call last):
  File "C:\Users\BODZIO\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 50, in wrapped
    ret = yield from coro(*args, **kwargs)
  File "C:\Users\BODZIO\Desktop\Discord Bot\DiscordBot.py", line 198, in leaderboard
    counter_id = str(res2[counter])
IndexError: tuple index out of range

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\BODZIO\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\bot.py", line 846, in process_commands
    yield from command.invoke(ctx)
  File "C:\Users\BODZIO\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 374, in invoke
    yield from injected(*ctx.args, **ctx.kwargs)
  File "C:\Users\BODZIO\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 54, in wrapped
    raise CommandInvokeError(e) from e
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: IndexError: tuple index out of range

#

@torn sphinx

#

?

#

hm

#

?

#

@ionic pecan

#

Can you help him then help me find out how to convert a list to a int or such what

#
Traceback (most recent call last):
  File "C:\Users\skinn\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 61, in wrapped
    ret = await coro(*args, **kwargs)
  File "C:\Users\skinn\Desktop\Alchemist\Alchemist.py", line 57, in work
    y = int(Balance) + x
TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\skinn\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\bot.py", line 898, in invoke
    await ctx.command.invoke(ctx)
  File "C:\Users\skinn\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 550, in invoke
    await injected(*ctx.args, **ctx.kwargs)
  File "C:\Users\skinn\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 70, in wrapped
    raise CommandInvokeError(e) from e
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'

ionic pecan
#

both of your errors are straightforward and you should be able to figure them out by yourself if you're working on a discord bot

torn sphinx
#

But I can't

#

I am not a Python Coder expert

#

I can just code decently..

#

you guys are helpers but you do not help you just say Hype do it yurself

#

I asked times and times

#

For a month

#

on this server..

#

and I have recieved nothing but information that I do not get bruh

vestal apex
#

there are a great many people that receive help with their discord bots here and understand that help

#

have you considered that there might be something wrong with your learning approach?

torn sphinx
#

I have asked for that help for 1 month

#

and also I recieved was information that I do not get

#

anyways this channel is about databases

vestal apex
#

then by all means, ask some clarifying questions

torn sphinx
#

I have..

vestal apex
#

what's your immediate problem?

torn sphinx
#

Loads

vestal apex
#

it sounds like they were not very good questions if you haven't gotten satisfactory answers

torn sphinx
#

Can I tell you what I have been saying all this time?

#

errors everything?

vestal apex
#

sure

torn sphinx
#

Okay

#
@client.command(pass_context=True)
async def leaderboard(ctx):
    res1 = c.execute("SELECT Coins FROM Users ORDER BY Coins DESC;")
    res1 = res1.fetchone()
    embed = discord.Embed(title="Most coins", description="The top users with the most Coins", color=0xfffafa)
    res2 = c.execute("SELECT UserID FROM Users ORDER BY Coins DESC;")
    res2 = res2.fetchone()
    for counter in range(0, 1):
        for member in ctx.message.server.members:
            counter_id = str(res2[counter])
            if counter_id == member.id:
                print(str(res1[counter]))
                embed.add_field(name=member.display_name, value=str(res1[counter]), inline=False)
                break
    await client.say(embed=embed)
#

This is good, but it will only show one person

#

since for counter in range(0, 1)

#

But there are 2 people in the database

#

I put

#
@client.command(pass_context=True)
async def leaderboard(ctx):
    res1 = c.execute("SELECT Coins FROM Users ORDER BY Coins DESC;")
    res1 = res1.fetchone()
    embed = discord.Embed(title="Most coins", description="The top users with the most Coins", color=0xfffafa)
    res2 = c.execute("SELECT UserID FROM Users ORDER BY Coins DESC;")
    res2 = res2.fetchone()
    for counter in range(0, 2):
        for member in ctx.message.server.members:
            counter_id = str(res2[counter])
            if counter_id == member.id:
                print(str(res1[counter]))
                embed.add_field(name=member.display_name, value=str(res1[counter]), inline=False)
                break
    await client.say(embed=embed)
vestal apex
#

why fetchone and not fetchall?

torn sphinx
#

idk

#

can I give error?

vestal apex
#

well it seems like you've got bigger problems than whatever error you're getting here

#

your function isn't doing what it's supposed to do very well

#

there's also much better ways to get Member objects in d.py

torn sphinx
#

ok

#
Ignoring exception in command leaderboard
Traceback (most recent call last):
  File "C:\Users\BODZIO\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 50, in wrapped
    ret = yield from coro(*args, **kwargs)
  File "C:\Users\BODZIO\Desktop\Discord Bot\DiscordBot.py", line 198, in leaderboard
    counter_id = str(res2[counter])
IndexError: tuple index out of range

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\BODZIO\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\bot.py", line 846, in process_commands
    yield from command.invoke(ctx)
  File "C:\Users\BODZIO\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 374, in invoke
    yield from injected(*ctx.args, **ctx.kwargs)
  File "C:\Users\BODZIO\AppData\Local\Programs\Python\Python36-32\lib\site-packages\discord\ext\commands\core.py", line 54, in wrapped
    raise CommandInvokeError(e) from e
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: IndexError: tuple index out of range

#

This is the error if I put the range('0,2')

tender hollow
#

Because fetchone() returns only one row.. so trying to access [1] isn't gonna work

torn sphinx
#

so fetchall()?

vestal apex
#

it would probably be a good thing to try

torn sphinx
#

ok

#

okay done that

#

Do I need to change this for counter in range(0, 1):?

#

into for counter in range(0, 2):

tender hollow
#

Why are you using range at all here?

torn sphinx
#

Because there are 2 people in the database

vestal apex
#

you should maybe just iterate over the rows you get back

#

hardcoding based on what's currently in your database doesn't make sense and isn't maintainable

torn sphinx
#

So should I change everything?