Formatierung und Unicode -> Fehler?

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.
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

Uiiiuii, ich glaube meine 'Programmierer'-Welt fällt in sich zusammen....

Ich habe das bisher so gemacht das ich die SQLs vorgefertigt hatte und dann direkt in die Execute-Methode weitergeleitet hatte.
Ich habe mich schon von Anfang an von der Command-Klasse verabschiedet (VB6-Bezogen). Jetzt, nach 15 Jahren, verstehe ich so langsam was die überhaupt macht.... :o :? :cry:

Nun gut, ich verstehe dank @BlackJack nun auch das WIESO.
Und das es bereits mehrere Male hier genannt wurde WAS und WIE man das richtig macht, hat mich erstmal erstaunt (weil ich es nicht realisiert hatte).
Jetzt, nachdem ich den Thread nochmals durchgelesen hatte, muss ich sagen das ich einfach Tomaten auf den Augen habe (vielleicht auch Würmer im Hirn?). Sirius: danke für deinen Link. Im Nachhinein erst verstehe ich was der mir das erklären will.... Sorry ;)
Benutzeravatar
martinjo
User
Beiträge: 189
Registriert: Dienstag 14. Juni 2011, 20:03

Ja wie jetzt? Keine Formatierung mit %s?? Jetzt verstehe ich gar nichts mehr.... :K
Ging mit letztens genauso: viewtopic.php?f=1&t=37040&p=283639#p283630
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

Es hat geklappt! Danke an alle! Ich verstehe auch die Vorgehensweise:
Die Execute-Methode des Cursors erwartet ein SQL-Statement mit den Platzhaltern %s. Der zweite Parameter ist ein Tuple mit den Werten. Leider ist es so das man eben jetzt die genaue Reihenfolge beachten muss aber damit kann ich leben.

Jetzt noch 2 Frage zu diesem bzw. einem verwandtem Thema:

1.) Sind die '%s'-Platzhalter zumindest ähnlich wie die C-Formatierung so daß ich für Strings ein %s angeben muss und für Zahlen ein %d und Fliesskomma ein %f usw.?
Geht da auch die erweiterte Definition wie etwa %f8.2 usw?
2.) Ich habe ein Problem bei einem Date-Feld. Wenn ich das Datum an das Datefeld übergebe, wessen Platzhalter aber das %s ist, bekomme ich eine Fehlermeldung
Warning: Data truncated for column 'date' at row 1
Das Datum ist selbstverständlich auch vollkommend falsch. So, ich weiß natürlich das es am Datumsformat liegt.
Wie bringe ich das vorhandene Datum (DD.MM.YYYY) in das mySQL-konforme Datum (YYYY-MM-DD)?
Es muss sicherlich eine Methode oder der Gleichen geben und nicht auf Stringebene 'auseinanderschnibseln' und andersherum zusammensetzen....
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Die Parameterisierung erfolgt nicht unbedingt per "%s": https://www.python.org/dev/peps/pep-0249/#paramstyle

Und nochmals: Das hat nichts mit Formatierung zu tun, darum auch keine Laengen etc. ... Die "%s" Variante ist etwas ungluecklich in der richtung.
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

@Cofi

Ach na klar, ich bin halt ein alter Esel....
Blöde Frage also mit der C-Formatierung mit %s -> ist keine Formatierung uns somit kann das mit dem %f8.2 (oder was auch immer) nicht funktionieren... und ich schlage imemr wieder in diese Richtung -> alter Esel halt... ;)

Das %s ist also ein Platzhalter. Und das %s hat dann auch nichts mit Strings zu tun? Wie definiere ich aber dann die Values oder muss ich das gar nicht? Kann ich Datum, Integers, Floats usw. einfach so übergeben? Gemischt und wie ich gerade will (nur eben entsprechend der Reihenfolge die mein definiertes SQL mit seinen Platzhaltern erwartet)?

Dann muss es auch kein %s sein sondern auch ein %IchbineinPlatzhalter ?

Und zum 2. Punkt: wie kann ich die Datumsangabe beeinflussen (MM.DD.YYYY -> YYYY-MM-DD)?


Nachtrag:

Habe gerade i o.g. Link gelesen unter Paramstyle:
WHERE name=%(name)s
Das nutzt mir aber nicht viel wenn ich ein Tulpe übergebe wo ich ja keine 'Keys' habe. Also muss ich wieder die Reihenfolge beachten und kann somit auch nur '%s' als Platzhalter verwenden, richtig?
Sirius3
User
Beiträge: 18264
Registriert: Sonntag 21. Oktober 2012, 17:20

@kaineanung: %s ist ein Platzhalter und es ist immer %s. Alternativ kannst Du den Parametern auch Namen geben %(blabla)s und als zweiten Parameter ein Wörterbuch übergeben. Datumsangaben übergibt man als Datetime-Objekte. PyMySQL sorgt schon für die richtige Übergabe,
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

Gibt es eine Funktion die mir aus DD.MM.YYYY ein YYYY-MM-DD macht?
Oder muss ich es, wie gehabt, zerlegen und dann ein Datumsobjekt erstellen indem ich dann datetime.date(iYear,iMonth,iDay) benutze?
(iYear, iMonth und iDay sind die zerlegten Teile des Datums)
BlackJack

@kaineanung: `datetime.datetime.strptime()` ist zum parsen von Zeichenketten in Datumsobjekte.
Benutzeravatar
pillmuncher
User
Beiträge: 1530
Registriert: Samstag 21. März 2009, 22:59
Wohnort: Pfaffenwinkel

@kaineanung:

Code: Alles auswählen

In [1]: import datetime

In [2]: datetime.datetime.strptime('03.12.2015', '%d.%m.%Y')
Out[2]: datetime.datetime(2015, 12, 3, 0, 0)
Doku hier.

Das noch: Hungarian Notation is the tactical nuclear weapon of source code obfuscation techniques.

Du möchtest vermutlich nicht, dass iYear, iMonth und iDay wirklich bloße Integers sind, denn guckstu:

Code: Alles auswählen

In [16]: iYear = -2**63-1

In [17]: iMonth = 13

In [18]: iDay = 32

In [19]: datetime.date(iYear, iMonth, iDay)
---------------------------------------------------------------------------
OverflowError                             Traceback (most recent call last)
<ipython-input-19-2fd7ec3ed157> in <module>()
----> 1 datetime.date(iYear, iMonth, iDay)

OverflowError: Python int too large to convert to C long

In [20]: datetime.date(2015, iMonth, iDay)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-20-6654798b77a3> in <module>()
----> 1 datetime.date(2015, iMonth, iDay)

ValueError: month must be in 1..12
In specifications, Murphy's Law supersedes Ohm's.
BlackJack

Um noch mal zu SQLAlchemy zurück zu kommen: Wenn man kein SQL schreiben möchte, dann kann das so aussehen (ungetestet und eine entsprechende `city_table` bzw. `City`-Klasse vorausgesetzt):

Code: Alles auswählen

# Core SQLAlchemy
cities = city_table.select(city_table.c.name == city['name']).execute().all()

# ORM
cities = session.query(City).filter_by(name=city['name']).all()
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

Gleicher Fehler an anderer Art und Stelle:

ich schreibe in eine Textdatei und bekomme bei Inhalten mit deutschen Umlauten den gleichen o.g. Fehler
UnicodeEncodeError: 'ascii' codec can't encode character u'\xfc' in position 29: ordinal not in range(128)
Der Code ist folgender:

Code: Alles auswählen

with open(tmpFile,"a+") as f: f.write(tmpValue+"\n")
tmpFile = Datei
tmpValue = Text welcher in die Datei angehängt werden soll.
Im tmpValue ist ein 'ü' enthalten.

Ich dachte ich schreibe das in diesen Thread weil der den gleichen Fehler behandelt bevor ich einen neuen eröffne. Ich hoffe das ist so ok für euch.

Ich habe ein wenig gegoogelt und gesehen das es auch die möglichkeit gibt als 3. Parameter in der 'open'-Funktion ein "utf-8" zu übergeben. Dies hat aber leider nicht geholfen.
Da bekomme ich dann an gleicher Stelle folgenden Fehler:
TypeError: an integer is required
Was kann ich tun? Was läuft falsch?
Danke schon einmal im Voraus für eure Mühe!
BlackJack

@kaineanung: Die Kodierung kann man bei `open()` bei Python 3 angeben. In Python 2 muss man dafür `io.open()` verwenden.
kaineanung
User
Beiträge: 145
Registriert: Sonntag 5. April 2015, 20:57

Ich habe das jetzt so gelöst das ich per [string].ecode("latin-1") den Text zuerst in ascii umwandlet bevor ich es zum schreiben an die Dateiklasse übergebe.
Ist das so auch korrekt?
Antworten