Jag stötte på ett liknande problem och efter ett par timmar av blod, svett och tårar fann jag att svaret helt enkelt kräver tillägg av en parameter.
Istället för
cursor = conn.cursor()
skriv
cursor = conn.cursor(name="my_cursor_name")
eller ännu enklare
cursor = conn.cursor("my_cursor_name")
Detaljerna finns på http://initd.org/psycopg/docs/usage.html#server-side-cursors
Jag tyckte att instruktionerna var lite förvirrande eftersom jag trodde att jag skulle behöva skriva om min SQL för att inkludera "DECLARE my_cursor_name ...." och sedan en "FETCH count 2000 FROM my_cursor_name" men det visar sig att psycopg gör allt för dig under huven om du helt enkelt skriver över standardparametern "name=None" när du skapar en markör.
Förslaget ovan att använda fetchone eller fetchmany löser inte problemet eftersom, om du lämnar namnparametern oinställd, kommer psycopg som standard att försöka ladda hela frågan i ram. Det enda andra du kan behöva (förutom att deklarera en namnparameter) är att ändra attributet cursor.itersize från standardvärdet 2000 till att säga 1000 om du fortfarande har för lite minne.