Fortlaufende ID erstellen und in DB schreiben

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
h0rnung
User
Beiträge: 46
Registriert: Mittwoch 28. Mai 2014, 11:41

Servus zusammen,

ich bastel immer noch an meinem Twitterstream herum: Dabei benutze ich als DB-Testversion die sqlite3 von Python. Mein aktueller Code sieht so aus

Code: Alles auswählen

from tweepy import Stream
from tweepy import OAuthHandler
from tweepy.streaming import StreamListener
import time
import datetime
import json
import sqlite3

connection = sqlite3.connect('twitterDB.db')
pointer = connection.cursor()

class listener(StreamListener):
    
    pointer.execute("CREATE TABLE tabelle(Followers INT)")
    def on_data(self, data):

        try:
            jsonData = json.loads(data)
            acc_followers = jsonData[u'user'][u'followers_count']
            pointer.execute("INSERT INTO tabelle(Followers) VALUES(?)",
                                (acc_followers))
            connection.commit()
            return True
        except BaseException, e: 
            print 'IMPORTANT ERROR,',str(e)
            time.slepp(5)

    def on_error(self, status):
        print status

auth = OAuthHandler(ckey, csecret)
auth.set_access_token(atoken, asecret)
twitterStream = Stream(auth, listener())
twitterStream.filter(track=["car"])
Hier wuerde ich jetzt gerne eine ID einbauen die pro tweet einen Zaehler nach oben geht. Da ich grundsaetzlich wenig Ahnung von Python habe und vieles davon nach Vorlage programmiert habe, konnte ich diese ID leider nicht erstellen.

Ich dachte grundsaetzlich koennte ich eine Variable (im Bsp var_id genannt) anfangs auf 0 setzten und spaeter in der "try-schleife" hochzaehlen lassen. So ungefaehr....

Code: Alles auswählen

[...]
class listener(StreamListener):
    
    var_id = 0
    pointer.execute("CREATE TABLE tabelle(Followers INT)")
    def on_data(self, data):

        try:
        [...]
        var_id = var_id + 1
        [...]
Ist mein Grundgedanke richtig? Was genau mache ich falsch? Und wie geht es richtig?

Danke und Gruesse

Ps: Ich vermute, dass es ein absolut bloeder Anfaengerfehler ist, wuerde mich aber dennoch ueber ernste und ausfuehrliche Hilfe freuen :)
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

h0rnung hat geschrieben:Hier wuerde ich jetzt gerne eine ID einbauen die pro tweet einen Zaehler nach oben geht. Da ich grundsaetzlich wenig Ahnung von Python habe und vieles davon nach Vorlage programmiert habe, konnte ich diese ID leider nicht erstellen.
Das Problem würde ich nicht mit Python lösen, da es dafür bereits eine Lösung in SQLite gibt: autoincrement.

Du solltest allerdings nicht davon ausgehen, dass du immer und ewig nur lückenlos vergebene IDs in der Tabelle hast. Spätestens wenn du einen Datensatz löschst hast du eine Lücke. Das ist aber zum Identifizieren einer Zeile exakt das, was man haben will. IDs sind eindeutig und haben auch eindeutig zu bleiben.
h0rnung
User
Beiträge: 46
Registriert: Mittwoch 28. Mai 2014, 11:41

Servus,

danke fuer die super Antwort ... habe leider dennnoch eine weitere Fragen, da ich ja hier keine "festgecodeten Werte" sondern eben Variablen in die Tabelle schreiben will. Aktueller Code sieht so aus:

Code: Alles auswählen

pointer.execute ("CREATE TABLE tabelle(Unix REAL, Datestamp TEXT, Followers INT, Friends INT, Favourites INT, Text TEXT)")
pointer.execute ("INSERT INTO tabelle(Unix,Datestamp,Followers,Friends,Favourites,Text) VALUES(?,?,?,?,?,?)",
                                         (time.time(),date,acc_followers,acc_friends,favourites_livetime,twitter.decode('utf-8')))
Folge ich den Anweisungen (auf der ansonst guten seite .. nochmal danke fuer den Tipp :) ) dann bleibt der Create-Table-Befehl gleich, aber der Insert-Befehl aendert sich. Was schreibe ich dann in die Value Zeile und daraus resultierend: Was schreibe ich in die Variablen Zeile?

Code: Alles auswählen

pointer.execute ("CREATE TABLE tabelle(Unix REAL, Datestamp TEXT, Followers INT, Friends INT, Favourites INT, Text TEXT)")
pointer.execute ("INSERT INTO tabelle(ROWID,Unix,Datestamp,Followers,Friends,Favourites,Text) VALUES(      WAS MUSS HIER HIN       ,?,?,?,?,?,?)",
                                         (     WAS MUSS HIER HIN     ,time.time(),date,acc_followers,acc_friends,favourites_livetime,twitter.decode('utf-8')))
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

h0rnung hat geschrieben:Was schreibe ich dann in die Value Zeile und daraus resultierend: Was schreibe ich in die Variablen Zeile?
Wenn Du /mes Ratschlag befolgst eben nix - denn dann vergibt SQLite den Wert für eine ID-Spalte selber. Allerdings hast Du ja gar keine in Deinem CREATE-Statement drin! So kann das ja nicht funktionieren...

Ich vermisse außerdem eine Primary Key Definition.

Zudem sollte man eigentlich das Anlegen vom Befüllen oder Auslesen trennen. Willst Du das wirklich bei jedem Start erneut tun?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
h0rnung
User
Beiträge: 46
Registriert: Mittwoch 28. Mai 2014, 11:41

Servus,

danke fuer die Antwort. Das Befuellen/Auslesen habe ich nur der uebersichthalber zusammengenommen. Das wird spaeter getrennt.

Ich habe im Create statement nichts drin stehen, da die Webside auf die /me verwiesen hat als Beispiel das anfuehrt:

For example:

CREATE TABLE test1(a INT, b TEXT);
INSERT INTO test1(rowid, a, b) VALUES(123, 5, 'hello');

... und da im Create statement auch nichts uebergeben wird. Soll ich also im Create Statement Rowid definieren und wenn ja welche Typ soll Rowid dann bekommen?

Zum Primary Key: Ich wuerde einfach die fortlaufende ID als primary Key benutzen - das aber spaeter erst im DataManagement Tool festlegen?

Gruesse und tausendDank!
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

h0rnung hat geschrieben: CREATE TABLE test1(a INT, b TEXT);
INSERT INTO test1(rowid, a, b) VALUES(123, 5, 'hello');
Der Text auf der Seite gibt noch etwas mehr her, aber ich verstehe durchaus, dass das nicht auf Anhieb verständlich ist. Die mit "INTEGER PRIMARY KEY" definierte Spalte entspricht der rowid.

Code: Alles auswählen

CREATE TABLE t1(
  a INTEGER PRIMARY KEY,
  b TEXT
);
Beim Einfügen gibt man dann einfach den Primärschlüssel nicht an.

Code: Alles auswählen

INSERT INTO t1 (b) VALUES ('i love relational databases')
Möchte man sicherstellen, dass eine ID niemals wiederverwendet wird, dann muss man beim Erstellen der Tabelle hinter "PRIMARY KEY" noch "AUTOINCREMENT" ergänzen.

Eventuell interessiert dich direkt nach dem Einfügen ja auch, welche rowid jetzt vergeben wurde. Von Python aus kommst du wie folgt an den Wert (gesetzt den Fall, dass dein Cursor cursor heißt).

Code: Alles auswählen

cursor.execute('INSERT INTO t1 (b) VALUES (?)', ('a tuple with the data',))
print(cursor.lastrowid)
h0rnung
User
Beiträge: 46
Registriert: Mittwoch 28. Mai 2014, 11:41

Super! Danke! Passt jetzt alles ... das Bsp ist echt verwirrend wie ich finde ...! Gruesse!
Antworten