Zu Sqlite3 methode convertieren

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
roof
User
Beiträge: 8
Registriert: Samstag 4. Februar 2012, 17:35

Servus Jungs,

Ich hab momentan meine Probleme Sqlite3. Ich hab die lib no net all zu oft benutzt um genau zu sein noch gar net.

Also hätt ich mal ne Frage dazu:


Ich hatte vorher die CPickle Lib benutzt um die daten in der Datenbank zu sichern. Also des isch speziel für CS:S (Eventscripts) also net wegen der 'steamid' und 'ev' wundern.

Code: Alles auswählen

my_dict_name[steamid]['feature1'] = 0/1
my_dict_name[steamid]['feature2'] = 0/1
my_dict_name[steamid]['feature3'] = 0/1
'''
.
.
.
.
und so weiter hald
'''
So und jetzt will ich des ganze mit Sqlite3 machen.

Soweit hab ichs bis jetzt:

Code: Alles auswählen

def player_activate(ev):
        for filename in alladdons: # in dem Sind alle featuere namen gespeichert.
                sqlite3.getCursor().execute("INSERT OR UPDATE INTO Premium (steamid, status) VALUES (?,?)",(ev['es_steamid'],filename))
                
                

class SQLiteDB():
        def load(self):
                self._connection = sqlite3.connect(es.getAddonPath('PremiumMod')+'/database/PremiumUsers.sqldb')
                self._cursor = self._connection.cursor()
                self._cursor.execute("CREATE TABLE IF NOT EXISTS Premium (steamid, status)")
        def getCursor(self):
                return self._cursor

sqlite3 = SQLiteDB()
Also ich möchte des eigentlich gleich wie oben machen ich möchte jedem "filename" (bzw. featruesname) einen (0/1 (False/ True) Zustand zuordnen.

Ich hoffe ich konnte des einigermasen verständlich erklären. Wäre gut wenn mir jemand ein paar zeilen zusammen coden kann (und bidde mit comments, damit ich auch verstehen kann wie und warum ma des macht).


Danke.

-
RoOF
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ehrlich gesagt verstehe ich nichts von Deinem Ansatz, Deinem Problem und was Du von uns konkret erwartest.

Als kleine Tipps vorab: PEP8 schreibt vier Spaces als Einrückung vor, nicht acht oder Tabs. Desweiteren ist Deine Klasse keine gute Idee und vor allem keine gute Umsetzung. Es gibt fertige ORMs a la SQLAlchemy. In Python verwendet man auch keine trivialen Getter und Setter - für komplexere Zugriffe gibt es Properties. Funktionsnamen sollten auch nicht mixedCase sondern klein und mit Unterstrichen benannt werden.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
roof
User
Beiträge: 8
Registriert: Samstag 4. Februar 2012, 17:35

Hyperion hat geschrieben:Ehrlich gesagt verstehe ich nichts von Deinem Ansatz, Deinem Problem und was Du von uns konkret erwartest.

Als kleine Tipps vorab: PEP8 schreibt vier Spaces als Einrückung vor, nicht acht oder Tabs. Desweiteren ist Deine Klasse keine gute Idee und vor allem keine gute Umsetzung. Es gibt fertige ORMs a la SQLAlchemy. In Python verwendet man auch keine trivialen Getter und Setter - für komplexere Zugriffe gibt es Properties. Funktionsnamen sollten auch nicht mixedCase sondern klein und mit Unterstrichen benannt werden.

Code: Alles auswählen

my_dict_name[steamid]['feature1'] = 0/1


So hatte ich des vorher gemacht und dann des dict dann mit cPickle abgespeichert.

Und des will ich jetzt mit sqlite3 umsetzen, da ich mich mit sqlite3 aber no net so auskenn brauche ich an paar coding "schnippsel" mitn paar comments, die mir des vielleicht verstaendlicher erklearen koennen.

/'|

Noch was allgemeines.

Warum darf ich net mi Tabs coden? Oder warum muessen des 4 spaces sein?
lunar

@roof: Wenn Du sqlite einsetzen möchtest, lese Dir vorher zumindest die rudimentären Grundlagen relationaler Datenbanken im Allgemeinen und deren Benutzung in Python im Speziellen an. Für ersteres reichen die entsprechenden Artikel auf Wikipedia, letzteres findest Du in der Dokumentation des sqlite-Moduls in der Standard-Bibliothek. Dort sind auch Beispiele zu finden. Dann erübrigt sich Deine Frage.

Zur Einrückung: Es gibt keinen zwingenden technischen Grund gegen die Verwendung von Tabulator-Zeichen, doch vier Leerzeichen sind der Standard. Sich in Punkt Stil und Namensgebung an den in der jeweiligen Community etablierten Standard, in diesem PEP 8, zu erhalten, erleichtert es anderen, Deinen Quelltext zu verstehen und auszuprobieren, was Dir wiederum zu Gute kommt, da andere Dir so besser bei Probleme helfen können.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

roof hat geschrieben:

Code: Alles auswählen

my_dict_name[steamid]['feature1'] = 0/1


So hatte ich des vorher gemacht und dann des dict dann mit cPickle abgespeichert.

Und des will ich jetzt mit sqlite3 umsetzen, ...
Das ist doch keine echte Beschreibung des Problems?!? Ist Dir denn das Konzept von relationalen Datenbanken vertraut? Also weißt Du prinzipiell, wie man Relationen aufbaut? Oder hast Du eher Schwierigkeiten, das SQLite-Modul von Python zu kapieren?

Was ist denn Deine Idee bezüglich der Tabellenstruktur? Aus einem verschachteltem Dictionary kann man sich nicht viel vorstellen bezüglich Relationen... eigentlich riecht das eher nach einem Dokumenten basierten Ansatz a la MongoDB oder CouchDB...

Also, rück mal ein paar Infos raus :-)
roof hat geschrieben: Warum darf ich net mi Tabs coden? Oder warum muessen des 4 spaces sein?
Du darfst alles - PEP8 ist der de facto Standard und der schreibt nun einmal vier Spaces vor. Wenn Du Dich da auch dran hältst, ist das auch von Vorteil für Dich, da die kompetenten Rezensoren diese Art von Code leichter lesen können :-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
roof
User
Beiträge: 8
Registriert: Samstag 4. Februar 2012, 17:35

Hyperion hat geschrieben:
roof hat geschrieben:

Code: Alles auswählen

my_dict_name[steamid]['feature1'] = 0/1


So hatte ich des vorher gemacht und dann des dict dann mit cPickle abgespeichert.

Und des will ich jetzt mit sqlite3 umsetzen, ...
Das ist doch keine echte Beschreibung des Problems?!? Ist Dir denn das Konzept von relationalen Datenbanken vertraut? Also weißt Du prinzipiell, wie man Relationen aufbaut? Oder hast Du eher Schwierigkeiten, das SQLite-Modul von Python zu kapieren?

Was ist denn Deine Idee bezüglich der Tabellenstruktur? Aus einem verschachteltem Dictionary kann man sich nicht viel vorstellen bezüglich Relationen... eigentlich riecht das eher nach einem Dokumenten basierten Ansatz a la MongoDB oder CouchDB...

Also, rück mal ein paar Infos raus :-)
roof hat geschrieben: Warum darf ich net mi Tabs coden? Oder warum muessen des 4 spaces sein?
Du darfst alles - PEP8 ist der de facto Standard und der schreibt nun einmal vier Spaces vor. Wenn Du Dich da auch dran hältst, ist das auch von Vorteil für Dich, da die kompetenten Rezensoren diese Art von Code leichter lesen können :-)

Ja richtig ich hab des problem wie des mit dem sqlite 3 modul mit den sql relationen abläuft.


# Also machmer mal an beispiel

Code: Alles auswählen

CREATE TABLE IF NOT EXISTS Premium (steamid, status) # Wir machen und den Table
INSERT OR UPDATE INTO Premium (steamid, status) VALUES (?,?)",(<steamid>, filename) # Also des würde jetzt so aussehen in der dict form my_dict_name[steamid]['filename'].
# Aber wie kann ich jetzt für des filename (bzw featurename) den True oder false status setzten. Und des isch mein Verständnis problem
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Du musst nicht alles stumpf zitieren, sondern nur die Teile, auf die Du Dich beziehst.

Du hast schon wieder zwei Dinge miteinander vermengt: Hast Du Verständnisschwierigkeiten mit relationalen Datenbanken oder spezielle, Python spezifische Fragen zum sqlite-Modul? Mir ist das immer noch nicht klar. Ich habe bisher auch noch keine Beschreibung zum Datenmodell gesehen; einfach eine ``create``-Statement hinzuklatschen reicht mir da nicht.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
roof
User
Beiträge: 8
Registriert: Samstag 4. Februar 2012, 17:35

Soo ich hoff ich habs jetzt wirklich verständlich hinbekommen

Code: Alles auswählen

#So ich versuchs jetzt nochmal so verständlich wie möglich zu erklären
# Jetztige Methode start --- 

my_dict = {}


def player_activate(ev): # Des wird  ausgeführt wenn der Spieler auf den Server joint
    steamid = ev['es_steamid'] # Die steamid isch die feste id in steam
    my_dict[steamid] = {} 
    for x in allfeatures: # allfeatures isch eine Liste in dere alle features (bzw. deren fraturesnamen gespeichert sind)
        my_dict[steamid][x] = 0 # (0/False) Wir fügen fügen zu jeder steamid die features hinzu
		
		
def save():
    file_players = open(es.getAddonPath('PremiumMod') + '/database.db','w') # Der Addons path
    cPickle.dump(my_dict, file_players) # Wir Speicherns hier
    file_players.close()
	
# Jetztige Methode end --- 

Code: Alles auswählen

# Soo und jetzt kommt mein Problem

#Zukünfigte Methode start --- 

def player_activate(ev):
    for x in allfeatures: # Soo machmer des gleiche wie oben , allfeatures isch eine Liste in dere alle features (bzw. deren fraturesnamen gespeichert sind)
        sqlite3.getcursor().execute("INSERT OR UPDATE INTO Premium (steamid, status) VALUES (?,?)",(ev['es_steamid'], x))
        '''So hier fügen wir wir oben die steam id des spielers hinzu und die featurs names,
            Ja und jetzt die x in the relation von 0 & 1 setzten bwz zu (True and False)
            Also so wie oben : Hier : my_dict[steamid][x] = 0
        '''
		
                
                
'''
Ihr habt mir schon gesagt das des ne schlechte Methode isch aber ich benutz die 
jetzt nur um des genauer und hoffentlich verständlicher zu erklären
'''
				
class sqlitedb():
    def load(self):
        self._connection = sqlite3.connect(es.getAddonPath('PremiumMod')+'/database/PremiumUsers.sqldb')
        self._cursor = self._connection.cursor()
        self._cursor.execute("CREATE TABLE IF NOT EXISTS Premium (steamid, status)")
    def getcursor(self):
        return self._cursor

sqlite3 = sqlitedb()

#Zukünfigte Methode end --- 
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Du hast also eine Menge von Spielern, die über die steam_id eindeutig bestimmbar sind. Desweiteren hast Du eine Featureliste, die für jeden Spieler gleich ist. Ein Feature kann also 0 oder 1 annehmen.

Erste Frage: Ist die Featureanzahl konstant? Wenn ja, kannst Du diese als Attribute nehmen. Wenn nein, musst Du eine n:m-Realtion "has_feature" aufbauen, der Du ggf. ein zusätzliches Attribut für den Status verpasst. Genau das sehe ich noch nicht. Irgend wie zweifel ich daran, dass Dir klar ist, wie man relationale Datenbanken benutzt.

Mich würde mal interessieren, wieso Du nicht bei der pickle-Lösung bleinbst? Wieso willst Du eine relationale Datenbank einsetzen?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
roof
User
Beiträge: 8
Registriert: Samstag 4. Februar 2012, 17:35

Hyperion hat geschrieben:Mich würde mal interessieren, wieso Du nicht bei der pickle-Lösung bleinbst? Wieso willst Du eine relationale Datenbank einsetzen?
Weil mir jemand der wo schon länger mit Python(Auch hier im forum aktiv) was zu tun hat als ich zu mir gesagt hat das Sqlite3 besser ist als CPickle um große Datenmengen abzuspeichern.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

roof hat geschrieben: Weil mir jemand der wo schon länger mit Python(Auch hier im forum aktiv) was zu tun hat als ich zu mir gesagt hat das Sqlite3 besser ist als CPickle um große Datenmengen abzuspeichern.
Hm... immer eine schlechte Idee, etwas nur aufgrund von Vermutungen zu tun ;-) Sofern Du das nicht direkt evaluieren kannst oder Probleme bereits jetzt schon merkst, würde ich doch die funktionierende Lösung beibehalten.

Nicht falsch verstehen, SQLite (und allgemein jede realtionale DB) hat seine Vorteile - die Frage ist nur, ob sich das bei Dir auch anbietet. Ich hätte bei deinen mageren bisherigen Problembeschreibungen eher an einen KV-Store a la Redis gedacht oder ggf. etwas wie MongoDB oder CouchDB.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
roof
User
Beiträge: 8
Registriert: Samstag 4. Februar 2012, 17:35

Ok dann werd ich den Pickle methode weiterhin benutzen ;)
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
was zu tun hat als ich zu mir gesagt hat das Sqlite3 besser ist als CPickle um große Datenmengen abzuspeichern.
Da würde ich so mal sagen: stimmt pauschal nicht. Wichtig ist auch, wie oft du an welches Daten dran musst.

Ansonsten stimme ich Hyperion zu: Es spricht einiges für ein KV-Store a la Redis.

Gruß, noisefloor
roof
User
Beiträge: 8
Registriert: Samstag 4. Februar 2012, 17:35

noisefloor hat geschrieben: Da würde ich so mal sagen: stimmt pauschal nicht. Wichtig ist auch, wie oft du an welches Daten dran musst.
Also um genau zu sein. Beim laden des Addons, und beim beenden wird hald dann der jetztige status der features wieder gespeichert.

noisefloor hat geschrieben: Ansonsten stimme ich Hyperion zu: Es spricht einiges für ein KV-Store a la Redis.
Hab net viel zu dem Thema gefunden.

http://www.python-forum.de/viewtopic.php?f=23&t=24107

Wäre des auch ne möglichkeit?
webspider
User
Beiträge: 485
Registriert: Sonntag 19. Juni 2011, 13:41

roof hat geschrieben:Hab net viel zu dem Thema gefunden.
http://www.google.de/search?q=redis+python
roof
User
Beiträge: 8
Registriert: Samstag 4. Februar 2012, 17:35

webspider hat geschrieben:
roof hat geschrieben:Hab net viel zu dem Thema gefunden.
http://www.google.de/search?q=redis+python

Welchen "großen" vorteil hat die Redis function gegenüber meiner jetztigen Methode?
deets

Das haengt von der Menge an Daten ab, die du hast. Ich vermute mal ganz ehrlich, dass du deinen Pickle-Kram beibehalten solltest - er ist flexibler als SQL, und solange du keine Performance-Probleme hast (wovon ich jetzt nix gelesen habe, korrigier mich wenn ich da falsch liege), solltest du das beibehalten.

Es sei denn es geht um's lernen von SQL.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

such' mal auf PyPi nach Redis. Da findest du alles - das "Standardmodul" für die Anbindung, div. Object-Mapper und noch vieles mehr.

Gruß, noisefloor
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

noisefloor hat geschrieben:such' mal auf PyPi nach Redis. Da findest du alles - das "Standardmodul" für die Anbindung, div. Object-Mapper und noch vieles mehr.
Overkill, much?

Ich stimme deets zu. Der OP will ein paar Datensätze speichen. Da braucht er keine Cloud-Lösung mit Sharding, Websockets, Map-Reduce und Eventual Consistency. Bitte mal den Begriff Verhältnismäßigkeit nachgucken, weil es ist klar, dass der OP mit SQLite schon seine Schwierigkeiten hat, da jetzt noch externe KV-Stores vorzuschlagen macht keinen Sinn.

Außer es geht ums lernen. Dann ja.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Leonidas hat geschrieben:Außer es geht ums lernen. Dann ja.
Das wollen wir doch alle & immer! ;-)

Gruß, noisefloor
Antworten