MySQLdb wrapper

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

EDIT: Die aktuellste Version ist immer hier: http://www.jensdiemer.de/Programmieren/ ... db_wrapper

Hier ist eine allgemeine Methode aus einer Klasse, dir eine SQL-select Anweisung darstellt:

Code: Alles auswählen

    def select( self, select_items, from_table, where=None, order=None, limit=None, debug=False ):
        """
        Allgemeine SQL-SELECT Anweisung
        where, order und limit sind optional
        mit debug=True wird das SQL-Kommando generiert, ausgegeben und sys.exit()

        where
        -----
        Die where Klausel ist ein wenig special.

        einfache where Klausel:
        where=("parent",0) ===> WHERE `parent`="0"

        mehrfache where Klausel:
        where=[("parent",0),("id",0)] ===> WHERE `parent`="0" and `id`="0"
        """

        select_String = ["`%s`" % i for i in select_items]

        SQLcommand = "SELECT " + ",".join( select_String )
        SQLcommand += " FROM `%s%s`" % ( dbconf["dbTablePrefix"], from_table )

        if where != None:
            if type( where[0] ) == type(""):
                # es ist nur eine where-Regel vorhanden.
                # Damit die folgenden Anweisungen auch gehen
                where = [ where ]

            where_string = ['`%s`="%s"' % (i[0],i[1]) for i in where]
            where_string = " and ".join( where_string )

            SQLcommand += ' WHERE %s' % where_string

        if order != None:
            SQLcommand += " ORDER BY `%s` %s" % order

        if limit != None:
            SQLcommand += " LIMIT %s,%s" % limit

        if debug == True:
            print ">>> (debug) SQL-command:"
            print "-"*80
            print SQLcommand
            print "-"*80
            sys.exit()

        RAWresult = self.get( SQLcommand )

        result = []
        itemlen = len(select_items)
        for line in RAWresult:
            temp = {}
            for i in xrange( itemlen ):
                temp[ select_items[i] ] = line[i]
            result.append( temp )

        return result
Benutzen kann man es so:

Code: Alles auswählen

    result = db.select(
            select_items    = ["id","name"],
            from_table      = "pages",
            where           = ("parent",0)
        )
Raus kommt dann die SQL-Anweisung:

Code: Alles auswählen

SELECT `id`,`name` FROM `lucid_pages` WHERE `parent`="0"
Als Ergebnis erhält man eine Liste mit einem Dict:

Code: Alles auswählen

[
   {'id': 1L, 'name': 'Start'},
   {'id': 13L, 'name': 'Programmieren'},
   {'id': 3L, 'name': 'Docs'},
   {'id': 7L, 'name': 'SiteMap'},
]
Oder aber man hat mehr als ein "where"-Teil:

Code: Alles auswählen

    result = db.select(
            select_items    = ["id","name"],
            from_table      = "pages",
            where           = [("parent",0),("id",1)]
        )
ergibt:

Code: Alles auswählen

SELECT `id`,`name` FROM `lucid_pages` WHERE `parent`="0" and `id`="1"

Code: Alles auswählen

[{'id': 1L, 'name': 'Start'}]
Das klappt alles ganz gut... Die Lösung mit der einfacher oder mehrfachen WHERE-Klausel finde ich allerdings gewöhnungsbedürftig. Hat dazu jemand eine bessere Idee?
Wobei es mir darum geht, das man die SQL-Klasse einfach benutzten kann, deswegen ist die komische Lösung eigentlich ganz praktisch.
Zuletzt geändert von jens am Donnerstag 20. Oktober 2005, 13:44, insgesamt 3-mal geändert.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Ich finde es macht die Select-Anweisung nicht unbedingt einfacher -- man muss die gleichen Daten nur anders aufschreiben und vor allem kann man nicht den Escape-Mechanismus der DB-API benutzen. Ich würde nie, oder nur in ganz wenigen Fällen, die Variablen mit '%s' und `%` in eine SQL Anweisung "hineinformatieren", sondern das escapen lieber der Datenbankanbindung überlassen.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

BlackJack hat geschrieben:vor allem kann man nicht den Escape-Mechanismus der DB-API benutzen.
Hm! Wie geht denn das?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
XT@ngel
User
Beiträge: 255
Registriert: Dienstag 6. August 2002, 14:36
Kontaktdaten:

Er meint sicher das optionale Argument 'parameters' von execute()
Wenn du die Werte deiner SQL Abfrage darüber festlegst brauchst du dir keine Gedanken darüber machen welche Zeichen ein Escape verlangen. Da dann die Implementierung des Python Moduls das erledigt.


MfG
Andreas
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

BlackJack hat geschrieben:man nicht den Escape-Mechanismus der DB-API benutzen.
Das würde ich gern ändern... Weiß aber nicht wie.
So geht's jendenfalls nicht:

Code: Alles auswählen

    SQLcommand = "SELECT %(select)s FROM lucid_pages"
    SQLparameter = { "select" : ("name","title") }

    cursor.execute( SQLcommand, SQLparameter )
    print cursor.fetchall()
und so auch nicht:

Code: Alles auswählen

    SQLcommand = "SELECT %s FROM lucid_pages"
    SQLparameter = [ ("name","title") ]

    cursor.execute( SQLcommand, SQLparameter )
    print cursor.fetchall()
Leider finde ich keine Doku bzw. Beispiele dazu :(

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Das würde auch mit normalem % bei Zeichenketten nicht funktionieren, oder? Stell Dir vor, das Komma im `execute()` wäre ein %.

Die DB API 2.0 wird in PEP 249 beschrieben.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Das hilft mir jetzt nicht wirklich weiter. die PEP 249 ist nicht sehr Aufschlussreich und reiht dich damit in doofe Dokus mit ein :?
Deutlich besser ist da die Doku zur pysqlite. Schön voll mit Beispielen! So mag ich Dokus :lol: Das gibt's bei Python leider viel zu wenig :cry:

Ich bin auf jeden Fall auf die Schlüsselwörter paramstyle und pyformat gestoßen. Muß ich erstmal sagen das ich pyformat verwenden will???

Noch ein Versuch:

Code: Alles auswählen

    SQLcommand = "SELECT %(select)s FROM lucid_pages LIMIT 0 , 3"
    SQLparameter = { "select":"title" }
    cursor.execute( SQLcommand, SQLparameter )
    print cursor.fetchall()
liefert:
(('title',), ('title',), ('title',))
und

Code: Alles auswählen

    SQLcommand = "SELECT %s FROM lucid_pages LIMIT 0 , 3"
    SQLparameter = ( "title", )
    cursor.execute( SQLcommand, SQLparameter )
    print cursor.fetchall()
liefert ebenfalls:
(('title',), ('title',), ('title',))
Warum ist das so?

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Kann mir niemand verraten wie es richtig geht???

Im übrigen hab ich bemerkt, wenn ich MySQLdb.string_literal() benutze, also quasi manuell escape, dann werden die Items mit '-Zeichen (einfache Anführungsstrich) umschlossen. Damit funktioniert aber der Aufruf nicht wirklich!

d.h. das geht:

Code: Alles auswählen

SELECT `id` FROM `lucid_pages` WHERE `name`='Programmieren'
oder das:

Code: Alles auswählen

SELECT `id` FROM `lucid_pages` WHERE `name`="Programmieren"
aber nicht das:

Code: Alles auswählen

SELECT 'id' FROM 'lucid_pages' WHERE 'name'='Programmieren'
Damit erhalte ich auch mit phpMyAdmin einen fehler:
#1064 - You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near ''lucid_pages' WHERE 'name'='Programmieren' LIMIT 0, 30' at line

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

jens hat geschrieben:Ich bin auf jeden Fall auf die Schlüsselwörter paramstyle und pyformat gestoßen. Muß ich erstmal sagen das ich pyformat verwenden will???
Du musst da nicht sagen was Du verwenden willst -- das Datenbankmodul sagt Dir mit diesem Attribut was Du verwenden darfst. Ich habe hier kein MySQLdb installiert -- was sagt das Attribut denn?
Noch ein Versuch:

Code: Alles auswählen

    SQLcommand = "SELECT %(select)s FROM lucid_pages LIMIT 0 , 3"
    SQLparameter = { "select":"title" }
    cursor.execute( SQLcommand, SQLparameter )
    print cursor.fetchall()
liefert:
(('title',), ('title',), ('title',))
und

Code: Alles auswählen

    SQLcommand = "SELECT %s FROM lucid_pages LIMIT 0 , 3"
    SQLparameter = ( "title", )
    cursor.execute( SQLcommand, SQLparameter )
    print cursor.fetchall()
liefert ebenfalls:
(('title',), ('title',), ('title',))
Warum ist das so?
Weil MySQLdb vielleicht nicht %s, also 'pyformat' benutzt? Das sieht aus wie das Ergebnis was Du in Deinem nächsten Beitrag erhälst.

Der Name `string_literal()` sagt es ja eigentlich schon: die Funktion ist dazu da um Zeichenkettenliterale zu Formatieren und keine Namen.

Code: Alles auswählen

select * from 'tabelle'
ist in SQL genauso ein Fehler wie folgendes in Python:

Code: Alles auswählen

'spam' = 10
Tabellen oder Variablennamen sind eben etwas anderes als literale Zeichenketten.
rayo
User
Beiträge: 773
Registriert: Mittwoch 5. November 2003, 18:06
Wohnort: Schweiz
Kontaktdaten:

Hi

So sollte ein normaler SQL-Befehl aussehen
SELECT id FROM lucid_pages WHERE name='Programmieren'
Besser aber du lässt SQL Escapen:

Code: Alles auswählen

cursor.execute("SELECT id FROM lucid_pages WHERE name=%s", ('Programmieren',))
oder mit mehreren argumenten:

Code: Alles auswählen

cursor.execute("SELECT id FROM lucid_pages WHERE name=%s and vorname=%s or ip=%s", ('Programmieren','thomas','192.168.1.1'))
Hilft dir das weiter?

Gruss
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Danke, das hilft mir schon, aber ich hänge gerade an einem weiteren Problem... Hier mal Code:

Code: Alles auswählen

        SQLcommand += "INSERT INTO %s ( %s,%s,%s,%s,%s ) VALUES (%s,%s,%s,%s,%s);"

        session_id = "9256b0df4614a1cc6ad278031f35cecc"
        timestamp = 1118086716.51
        client_IP = "192.168.6.3"
        domain = "192.168.6.3"
        data = "TEST"

        self.db_cursor.execute( SQLcommand,
            (
            self.sql_tablename,
            "session_id", "timestamp", "ip", "domain_name", "session_data",
            session_id, timestamp, client_IP, domain, data
            )
        )
SQL mekert immer:
ProgrammingError: (1064, "You have an error in your SQL syntax. Check the manual that corresponds to your MySQL server version for the right syntax to use near ';\nINSERT INTO 'lucid_session_data' ( 'session_id','timestamp','")
args = (1064, "You have an error in your SQL syntax. Check the...'lucid_session_data' ( 'session_id','timestamp','")
Ich habe auch mehrere Varianten durch probiert... Alles selber escapen, nur die VALUES-Werte vom SQL-Modul escapen lassen und halt diese Version... Der SQL-Fehler ist allerdings immer der selbe...
Mit phpmyadmin geht's allerdings...


EDIT: Komisch, jetzt geht's anscheinend damit:

Code: Alles auswählen

        SQLcommand += " INSERT INTO %s" % self.sql_tablename
        SQLcommand += " ( `session_id` , `timestamp` , `ip` , `domain_name` , `session_data` )"
        SQLcommand += " VALUES (%s, %s, %s, %s, %s);"

        debug( SQLcommand )
        self.db_cursor.execute(
            SQLcommand,
            ( session_id, time.time(), self.client_IP, self.client_domain_name, session_data )
        )

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Neue Version!
Kann nun UPDATE und INSERT.

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: UTF-8 -*-

# by jensdiemer.de (steht unter GPL-License)

"""
MySQLdb wrapper

Allgemeine Routinen für eine einfachere SQL Benutzung

Benötigt MySQLdb download unter:
http://sourceforge.net/projects/mysql-python/


Information
-----------
Generell wird keine Tracebacks abgefangen, das muß immer im eigentlichen
Programm erledigt werden!

Wie man die Klasse benutzt, kann man unten sehen ;)



ToDo
----
    * update und insert benutzen das SQLdb-Escapeing. Die select-Funktion allerdings
      noch nicht!
"""

__version__="0.0.4"

__history__="""
v0.0.4
    - Bugfixes
    - Debugfunktion eingefügt
    - Beispiel hinzugefügt
    - SQL "*"-select verbessert.
v0.0.3
    - Allgemeine SQL insert und update Funktion eingefügt
    - SQL-where-Parameter kann nun auch meherere Bedingungen haben
v0.0.2
    - Allgemeine select-SQL-Anweisung
    - Fehlerausgabe bei fehlerhaften SQL-Anfrage
v0.0.1
    - erste Release
"""



try:
    import MySQLdb
except ImportError:
    print "Content-type: text/html\n"
    print "<h1>Error</h1>"
    print "<h3>MySQLdb import error! Modul 'python-mysqldb' not installed???</h3>"
    import sys
    sys.exit(0)




class db:
    """
    Klasse, die nur allgemeine SQL-Funktionen beinhaltet
    """
    def __init__( self, *args, **kwargs ):
        self.db             = MySQLdb.connect( *args, **kwargs )
        self.cursor         = self.db.cursor()
        self.tableprefix    = ""
        self.debug          = False

    def get( self, SQLcommand ):
        "kombiniert execute und fetchall"
        self.cursor.execute(
                SQLcommand.replace("$tableprefix$", self.tableprefix)
            )
        return self.cursor.fetchall()

    def _make_values( self, values ):
        "Erstellt einen values-Tuple für cursor.execute()"
        if len( values ) == 1:
            return (values[0],)
        else:
            return tuple( values )

    def insert( self, table, data ):
        """
        Vereinfachter Insert, per dict
        data ist ein Dict, wobei die SQL-Felder den Key-Namen im Dict entsprechen muß!
        """
        items   = data.keys()
        values  = self._make_values( data.values() )

        SQLcommand = "INSERT INTO %(prefix)s%(table)s ( %(items)s ) VALUES ( %(values)s );" % {
                "prefix"        : self.tableprefix,
                "table"         : table,
                "items"         : ",".join( items ),
                "values"        : ",".join( ["%s"]*len(values) ) # Platzhalter für SQLdb-escape
            }

        if self.debug:
            print "-"*80
            print "db.insert - Debug:"
            print "SQLcommand.:",SQLcommand
            print "values.....:",values
            print "-"*80

        self.cursor.execute( SQLcommand, values )

    def update( self, table, data, where, limit=None ):
        """
        Vereinfachte SQL-update Funktion
        """
        items   = data.keys()
        values  = self._make_values( data.values() )

        if not limit == None:
            limit = "LIMIT %s" % limit
        else:
            limit = ""

        SQLcommand = "UPDATE %(prefix)s%(table)s SET %(set)s WHERE %(where)s %(limit)s;" % {
                "prefix"    : self.tableprefix,
                "table"     : table,
                "set"       : ",".join( [str(i)+"=%s" for i in items] ),
                "where"     : "%s='%s'" % (where[0],where[1]),
                "limit"     : limit
            }

        if self.debug:
            print "-"*80
            print "db.update - Debug:"
            print "SQLcommand.:",SQLcommand
            print "values.....:",values
            print "-"*80

        self.cursor.execute( SQLcommand, values )

    def select( self, select_items, from_table, where=None, order=None, limit=None ):
        """
        Allgemeine SQL-SELECT Anweisung
        where, order und limit sind optional

        where
        -----
        Die where Klausel ist ein wenig special.

        einfache where Klausel:
        where=("parent",0) ===> WHERE `parent`="0"

        mehrfache where Klausel:
        where=[("parent",0),("id",0)] ===> WHERE `parent`="0" and `id`="0"
        """

        SQLcommand = "SELECT " + ",".join( select_items )
        SQLcommand += " FROM `%s%s`" % ( self.tableprefix, from_table )

        if where != None:
            if type( where[0] ) == str:
                # es ist nur eine where-Regel vorhanden.
                # Damit die folgenden Anweisungen auch gehen
                where = [ where ]

            where_string = []
            for item in where:
                if type(item[1]) == int:
                    where_string.append( '`%s`=%s' % (item[0],item[1]) )
                else:
                    where_string.append( '`%s`="%s"' % (item[0],item[1]) )

            where_string = " and ".join( where_string )

            SQLcommand += ' WHERE %s' % where_string

        if order != None:
            SQLcommand += " ORDER BY `%s` %s" % order

        if limit != None:
            SQLcommand += " LIMIT %s,%s" % limit

        if self.debug:
            print "-"*80
            print "db.select - Debug:"
            print "SQLcommand:", SQLcommand

        RAWresult = self.get( SQLcommand )

        if self.debug:
            print "RAWresult:", RAWresult
            print "-"*80


        if select_items == "*":
            # Spezielle Auswertung bei "SELECT *"-Anfragen
            # Erstellt ein Dict mit den Namen der Tabellen-Felder
            select_items = self.cursor.description
            select_items = [i[0] for i in select_items]

        # Daten aufbereiten -> Packe alle Daten in ein Dict
        result = []
        itemlen = len(select_items)
        for line in RAWresult:
            temp = {}
            for i in xrange( itemlen ):
                temp[ select_items[i] ] = line[i]
            result.append( temp )

        return result

    def dump_select_result( self, result ):
        print "*** dumb select result ***"
        for i in xrange( len(result) ):
            print "%s - %s" % (i, result[i])

    def close( self ):
        "Connection schließen"
        self.db.close()




if __name__ == "__main__":
    db = db(
            host    = "localhost",
            user    = "UserName",
            passwd  = "UserPassword",
            db      = "DatabaseName"
        )
    # Prefix for all SQL-commands:
    db.tableprefix = "test_"
    
    # Prints all SQL-command:
    db.debug = True

    SQLcommand  = "CREATE TABLE %sTestTable (" % db.tableprefix
    SQLcommand += "id INT( 11 ) NOT NULL AUTO_INCREMENT,"
    SQLcommand += "data1 VARCHAR( 50 ) NOT NULL,"
    SQLcommand += "data2 VARCHAR( 50 ) NOT NULL,"
    SQLcommand += "PRIMARY KEY ( id )"
    SQLcommand += ") COMMENT = '%s - temporary test table';" % __file__

    print "\n\nCreat a temporary test table - execute SQL-command directly."
    try:
        db.cursor.execute( SQLcommand )
    except Exception, e:
        print "Can't create table: '%s'" % e


    print "\n\nSQL-insert Function:"
    db.insert(
            table = "TestTable",
            data  = { "data1" : "Value A 1", "data2" : "Value A 2" }
        )

    print "\n\nadds a new value:"
    db.insert(
            table = "TestTable",
            data  = { "data1" : "Value B 1", "data2" : "Value B 2" }
        )


    print "\n\nSQL-select Function (db.select):"
    result = db.select(
            select_items    = ["id","data1","data2"],
            from_table      = "TestTable",
            #~ where           = ("parent",0)#,debug=1
        )
    db.dump_select_result( result )


    print "\n\nUpdate an item (db.update)."
    data = { "data1" : "NewValue1!"}
    db.update(
            table   = "TestTable",
            data    = data,
            where   = ("id",1),
            limit   = 1
        )


    print "\n\nSee the new value (db.select):"
    result = db.select(
            select_items    = ["data1"],
            from_table      = "TestTable",
            where           = ("id",1)
        )
    db.dump_select_result( result )


    print "\n\nSee all values via SQL '*'-select:"
    result = db.select(
            select_items    = "*",
            from_table      = "TestTable",
            #~ where           = ("id",1)
        )
    db.dump_select_result( result )


    print "\n\nDelete the temporary test Table."
    db.cursor.execute( "DROP TABLE %sTestTable" % db.tableprefix )


    print "\n\nClose SQL-connection."
    db.close()
Die Testausgabe von __main__:
Creat a temporary test table - execute SQL-command directly.


SQL-insert Function:
--------------------------------------------------------------------------------
db.insert - Debug:
SQLcommand.: INSERT INTO test_TestTable ( data1,data2 ) VALUES ( %s,%s );
values.....: ('Value A 1', 'Value A 2')
--------------------------------------------------------------------------------


adds a new value:
--------------------------------------------------------------------------------
db.insert - Debug:
SQLcommand.: INSERT INTO test_TestTable ( data1,data2 ) VALUES ( %s,%s );
values.....: ('Value B 1', 'Value B 2')
--------------------------------------------------------------------------------


SQL-select Function (db.select):
--------------------------------------------------------------------------------
db.select - Debug:
SQLcommand: SELECT id,data1,data2 FROM `test_TestTable`
RAWresult: ((1L, 'Value A 1', 'Value A 2'), (2L, 'Value B 1', 'Value B 2'))
--------------------------------------------------------------------------------
*** dumb select result ***
0 - {'data1': 'Value A 1', 'id': 1L, 'data2': 'Value A 2'}
1 - {'data1': 'Value B 1', 'id': 2L, 'data2': 'Value B 2'}


Update an item (db.update).
--------------------------------------------------------------------------------
db.update - Debug:
SQLcommand.: UPDATE test_TestTable SET data1=%s WHERE id='1' LIMIT 1;
values.....: ('NewValue1!',)
--------------------------------------------------------------------------------


See the new value (db.select):
--------------------------------------------------------------------------------
db.select - Debug:
SQLcommand: SELECT data1 FROM `test_TestTable` WHERE `id`=1
RAWresult: (('NewValue1!',),)
--------------------------------------------------------------------------------
*** dumb select result ***
0 - {'data1': 'NewValue1!'}


See all values via SQL '*'-select:
--------------------------------------------------------------------------------
db.select - Debug:
SQLcommand: SELECT * FROM `test_TestTable`
RAWresult: ((1L, 'NewValue1!', 'Value A 2'), (2L, 'Value B 1', 'Value B 2'))
--------------------------------------------------------------------------------
*** dumb select result ***
0 - {'data1': 'NewValue1!', 'id': 1L, 'data2': 'Value A 2'}
1 - {'data1': 'Value B 1', 'id': 2L, 'data2': 'Value B 2'}


Delete the temporary test Table.


Close SQL-connection.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Ich hab mich immer gefragt, warum das values-Tuple für cursor.execute() bei einem Eintrag zusätzlich noch ein Komma haben müßen.... Nun weiß ich es:

Code: Alles auswählen

for i in ( "TEST" ):
    print i

for i in ( "TEST", ):
    print i
Ergibt:
T
E
S
T
TEST

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Das Komma brauchst Du, wenn es ein Tupel sein soll. Ein Tupel mit einem Element ist sonst nicht von normalen Klammern zu Unterscheiden. Beispiel: ``(5)`` ist einfach nur eine 5, während (5,) ein Tupel mit einer 5 als einzigem Element ist.
fs111
User
Beiträge: 170
Registriert: Samstag 15. November 2003, 11:42
Kontaktdaten:

Nur eine kleine Anregung, Strings braucht man nicht mit + zusammenkleben, wenn sie über mehrere Zeilen gehen, das ist eh furchtbar langsam, einfach """"""-Multiline-Strings benutzen.

fs111
Pydoc-Integration in vim - Feedback willkommen: http://www.vim.org/scripts/script.php?script_id=910
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

fs111 hat geschrieben:""""""-Multiline-Strings benutzen.
Das ist eigentlich eine schöne Geschichte in Python... Nur hat man entweder doofen Source-Code oder einige Leerzeilen drin :(

Da benutze ich lieber +=

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

Ich finde beides hässlich. ``+=`` führt unnötige Operationen durch und bei Multiline-Zeichenketten muss man sie entweder an den linken Rand "kleben" oder führende Leerzeichen in jeder Zeile in Kauf nehmen oder beseitigen. Ich benutze immer Klammern und den Umstand, das Zeichenketten, die nur durch Whitespace voneinander getrennt sind, beim laden/übersetzen zu einer Zeichenkette werden:

Code: Alles auswählen

a = '''Hallo
Welt!'''
b = 'Hallo\n'
b += 'Welt!'
c = ('Hallo\n'
     'Welt!')
a == b == c
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ob das besser ist lässt sich streiten, aber immerhin:

Code: Alles auswählen

#!/usr/bin/env python
# -*- encoding: latin-1 -*-

import textwrap

def testdef():
    t = """
    Ein Text. Erste Ebene.
    Noch eine Ebene. Sollte nicht eingerückt werden.
        Letzte Ebene. Sollte eingerückt werden"""
    print t
    t = textwrap.dedent(t)
    print t

testdef()
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Erhlich gesagt, kann ich mich mit beiden nich so richtig anfreuden :(

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten