Fetchall() limited in python

Asked

Viewed 2,321 times

0

I’m making a code that makes a query in postgres and returns in a list, but this is giving memory error. The part of the code that does this:

c = conn.cursor()
c.execute("SELECT latitude, longitude, gid FROM pontos")  
records = c.fetchall() #pega todos os resultados do select e armazena em uma tupla
e = conn.cursor()
e.execute("SELECT precipitacaoh, gidgeo_fk FROM historico")
records2 = e.fetchall()

How do I take, for example, the 100 elements of the query and store on the disk, and then take the next 100 elements, until I store the whole query? Not to overload the system.

  • By your comment below, your error has nothing to do with the amount of data - include the error message that actually happens. S and the code has changed, it might be better to ask another question.

  • In fact, there is no error, the system simply hangs. I already left the code running an entire night, I had to restart the computer and had not included any entries in the new database.

1 answer

1

It is possible to do this yes - I wonder if it will be useful to simply store the values in a text file: in general recover the desired data in the database and process them directly is better than Pear the same data from a text file, where we have no indexing tool, ways to search, etc...

It is very strange to me that you are having a "memory error" with records as simple as these - even millions of records should not exhaust the memory of a system with RAM in the gigabyte home.

Now, turning specifically to what you ask - the Python database connectors - all - implement beyond the fetchall, the fetchmany - which returns only the requested number of records.

So, one way to transfer a query to a local file (which I don’t consider useful - unless that’s all you want to do with the data) would be:

import csv
c = conn.cursor()
c.execute("SELECT latitude, longitude, gid FROM pontos")

with open("arquivo_destino.csv", "wt") as file_:
    writer  = csv.writer(file_)
    writer.writerow(("latitude", "longitude"))
    records = True
    while records:
        records = c.fetchmany(100)
        writer.writerows(records)
...

The connection cursor itself can also be used as an iterator, returning a query result at a time if it is used in a query - this way of using is better if you are consuming your data, rather than simply writing it to a local file:

c = conn.cursor()
c.execute("SELECT latitude, longitude, gid FROM pontos")
for record in c:
      # do things with row result

(but I’ve seen bugle implementations of coenxions to the bank in which interacting the cursor that way was very slow - if that’s the case, better make a combination with fetchmany as well).

  • I made the following modification to my code, but it keeps crashing. I’m trying to migrate a relational database to a graph database. http://pastebin.com/rG3kMxuv

  • In the code you linked you create the files in a command "with" - and create the writers (Writers) CSV - only the idea of the command "with" is precisely Ensure that the file is closed as soon as you leave it. Then your Writes get a reference to closed files - it won’t even work. With is something that works best in critical portions of the program where multiple files will be opened (hundreds or thousands of times) to prevent leakage of operating system resources if some are not closed. Nesse".

  • but I still don’t understand why you can’t log into the new database immediately after reading SQL - why you need the intermediate CSV?

  • In fact, what I wanted was to take the records from the database, for example from 100 in 100 records, and insert them into the new database, and continue until all the data was entered. Because if I do what I do in the original code: Records = c.fetchall(), it totally crashes the system. So I wanted to take 100 out of 100 and already go inserting. Got it?

Browser other questions tagged

You are not signed in. Login or sign up in order to post.