Seite 1 von 1
MSSQL - Bestimmtes Datum auslesen
Verfasst: Donnerstag 17. Februar 2022, 20:18
von Juliusvanvern
Hallo zusammen.
Ich möchte gerne von einer "winzigen" MS-SQL-DB nur die Werte auslesen, die ein bestimmtes Datum haben.
Ich habe mit pyodbc eine Verbindung zu der Datenbank hergestellt und dachte mir ich nutze pandas zur Datenanalyse (pd)
Im MS-SQL-Server Management Studio habe ich eine Query getestet um alle Zeilen anzuzeigen welche ein bestimmtes Datum haben. Das funktioniert auch:
Code: Alles auswählen
SELECT * FROM kunden.dbo.kunden_kundennamen
WHERE EndDate = '2021-10-18'
Ganz unbedarft bin ich nun heran gegangen und habe versucht dies in Python zu bewerkstelligen. Aber es klappt leider nicht.
Fehler: "SyntaxError: invalid syntax. Perhaps you forgot a comma?" an einem bestimmten Punkt habe ich wohl was vergessen.
Code: Alles auswählen
from typing import ValuesView
import pyodbc
import pandas as pd
import sqlalchemy as sa
cnxn = pyodbc.connect("Driver={ODBC Driver 17 for SQL Server};"
"Server=DESKTOP-UP2PHSF\SQLEXPRESS;"
"Database=kunden;"
"Trusted_Connection=yes;")
EndDate = pd.read_sql_query('SELECT * FROM kunden.dbo.kunden_kundennamen WHERE EndDate = '2021-10-18'', cnxn)
print(EndDate)
Wenn ich mit folgender Query testweise alles auslesen möchte, funktioniert es.
Code: Alles auswählen
data = pd.read_sql_query('SELECT * FROM kunden.dbo.kunden_kundennamen', cnxn)
print(data)
Kann es sein, das ich ggf. das Datum konvertieren muss? Vielleicht erwartet er ja ein String und ich versuche aber ein Datumsformat auszulesen.
PS: EndDate hat den Datentyp Date in MSSQL
Könnt ihr mir auf die Sprünge helfen? Das währe sehr nett. Vielen Dank
Re: MSSQL - Bestimmtes Datum auslesen
Verfasst: Donnerstag 17. Februar 2022, 20:23
von Sirius3
Strings müssen in Anführungszeichen gesetzt werden. Jetzt schau mal, wo Deine Strings anfangen und wo sie aufhören. Das kann man schon gut an der Farbe erkennen.
Re: MSSQL - Bestimmtes Datum auslesen
Verfasst: Donnerstag 17. Februar 2022, 20:53
von Juliusvanvern
Sirius3 hat geschrieben: ↑Donnerstag 17. Februar 2022, 20:23
Strings müssen in Anführungszeichen gesetzt werden. Jetzt schau mal, wo Deine Strings anfangen und wo sie aufhören. Das kann man schon gut an der Farbe erkennen.
Ich habe es nun so gemacht, da später die Eingabe im Deutschen Datumsformat getätigt werden soll.
Code: Alles auswählen
EndDate = pd.read_sql_query('SELECT * FROM kunden.dbo.kunden_kundennamen WHERE EndDate = CONVERT(DATETIME, '"18-10-2021"', 104)', cnxn)
print(EndDate)
Zumindest bekomme ich keinen Fehler mehr, aber meine Abfrage bleibt leer.
Meine Query in der Datenbank direkt, funktioniert und liefert mir alle drei Werte mit dem Datum.
Code: Alles auswählen
SELECT * FROM kunden.dbo.kunden_kundennamen
WHERE EndDate = CONVERT(datetime, '18-10-2021', 104)
Kann es sein, das ich mit der Angabe nach einem String suche, er aber eigentlich ein Format vom Typ Date erwartet?
Re: MSSQL - Bestimmtes Datum auslesen
Verfasst: Donnerstag 17. Februar 2022, 20:56
von sparrow
Die Antwort von Sirius3 bleibt korrekt.
Zeig doch mal, wo die Zeichenkette, die die SQL-Query enthält, beginnt und wo sie aufhört.
Re: MSSQL - Bestimmtes Datum auslesen
Verfasst: Donnerstag 17. Februar 2022, 21:06
von Juliusvanvern
sparrow hat geschrieben: ↑Donnerstag 17. Februar 2022, 20:56
Die Antwort von Sirius3 bleibt korrekt.
Zeig doch mal, wo die Zeichenkette, die die SQL-Query enthält, beginnt und wo sie aufhört.
Nicht sicher was du jetzt genau meinst, aber ich versuche es zu beantworten.
Meine Query ist ja das
Code: Alles auswählen
SELECT * FROM kunden.dbo.kunden_kundennamen WHERE EndDate = CONVERT(DATETIME, '"18-10-2021"', 104)
Den auszulesenden Wert habe ich nun in doppelte Hochkomma gesetzt. Damit die Query generell funktioniert muss ich sie in ' ' einpacken.
Re: MSSQL - Bestimmtes Datum auslesen
Verfasst: Donnerstag 17. Februar 2022, 21:20
von sparrow
Also, wenn du der Parser bist, und du siehst diese Zeichenkettendefinition:
Code: Alles auswählen
'SELECT * FROM kunden.dbo.kunden_kundennamen WHERE EndDate = CONVERT(DATETIME, '"18-10-2021"', 104)'
Dann guckst du dir die vorne and und weißt: Sehr gut eine Zeichenkette, die mit einem einfachen Hockomma beginnt. Ich weiß, dass die bei dem nächsten nicht maskierten einfachem Hochkomma endet.
Das nächste nicht masierte Hochkomma ist nicht nach der schließenden Klammer. Das sieht man - wie hier bereits angemerkt - auch an der Einfärbung durch das Syntax Highlighting.
Da man in Python mindestens 4 Arten hat um Zeichenketten zu kennzeichnen, würde ich vorschalgen, du nimmst nocht ausgerechnet ein einfaches Hochkomma, dass du offensichtlich in der Zeichenkette selbst noch verwenden willst.
Re: MSSQL - Bestimmtes Datum auslesen
Verfasst: Donnerstag 17. Februar 2022, 21:51
von Juliusvanvern
Ich hab es nun so.
Code: Alles auswählen
EndDate = pd.read_sql_query('SELECT EndDate FROM kunden.dbo.kunden_kundennamen WHERE EndDate = CONVERT(DATETIME, ''18-10-2021'', 104)', cnxn) # Funktioniert, aber Data Frame ist leer
print(EndDate)
Jedoch bleibt der Ausgabe wert leer.
Wenn ich es so versuche
Code: Alles auswählen
ndDate = pd.read_sql_query('SELECT * FROM kunden.dbo.kunden_kundennamen WHERE EndDate = ''2021-10-18''', cnxn) # Hier kommt date is incompatible with int
print(EndDate)
gibt er mir ein Int zurück was ja in dem Fall nicht mit dem Type Date zusammen passt.
Ich hab das Gefühl, ich laufe die ganze Zeit um den Fehler drum herum, aber sehe ihn nicht.
Irgendwann bekomme ich das bestimmt noch hin.
Re: MSSQL - Bestimmtes Datum auslesen
Verfasst: Donnerstag 17. Februar 2022, 22:43
von Sirius3
Schau Dir doch einfach mal an, was Du hier für literale Strings erzeugst.
'abc''123' ist das selbe wie 'abc123' weil einfach zwei Strings zusammengesetzt werden.
Re: MSSQL - Bestimmtes Datum auslesen
Verfasst: Donnerstag 17. Februar 2022, 22:48
von pillmuncher
Code: Alles auswählen
>>> s = 'abc''123'
>>> s
'abc123'
>>> s = 'abc' '123'
>>> s
'abc123'
>>> s = 'abc'"123"'def'
>>> s
'abc123def'
Re: MSSQL - Bestimmtes Datum auslesen
Verfasst: Freitag 18. Februar 2022, 03:13
von __blackjack__
Das mit `pyodbc` so zu verwenden kann vielleicht funktionieren, muss es aber nicht, denn die Dokumentation von Pandas garantiert das ausschliesslich für das `sqlite3`-Modul. Wenn man andere DBs verwenden will, erwartet Pandas, das man über SQLAlchemy geht. Die Dokumentation zu dem Argument ist da sehr deutlich:
con : SQLAlchemy connectable, str, or sqlite3 connection
Using SQLAlchemy makes it possible to use any DB supported by that
library. If a DBAPI2 object, only sqlite3 is supported.
`cnxn` ist übrigens kein wirklich guter Name.
Re: MSSQL - Bestimmtes Datum auslesen
Verfasst: Freitag 18. Februar 2022, 08:45
von Juliusvanvern
__blackjack__ hat geschrieben: ↑Freitag 18. Februar 2022, 03:13
Das mit `pyodbc` so zu verwenden kann vielleicht funktionieren, muss es aber nicht, denn die Dokumentation von Pandas garantiert das ausschließlich für das `sqlite3`-Modul. Wenn man andere DBs verwenden will, erwartet Pandas, das man über SQLAlchemy geht. Die Dokumentation zu dem Argument ist da sehr deutlich:
con : SQLAlchemy connectable, str, or sqlite3 connection
Using SQLAlchemy makes it possible to use any DB supported by that
library. If a DBAPI2 object, only sqlite3 is supported.
`cnxn` ist übrigens kein wirklich guter Name.
Ahh okay. Vielen Dank. Dann werde ich mir mal die Dokumentation von SQLAlchemy zu Gemüte führen.
Re: MSSQL - Bestimmtes Datum auslesen
Verfasst: Freitag 18. Februar 2022, 12:32
von Juliusvanvern
Sirius3 hat geschrieben: ↑Donnerstag 17. Februar 2022, 22:43
Schau Dir doch einfach mal an, was Du hier für literale Strings erzeugst.
'abc''123' ist das selbe wie 'abc123' weil einfach zwei Strings zusammengesetzt werden.
Danke dir Sirius, das hab ich gar nicht so gesehen.
Ich habe es nun versucht so umzusetzen.
Verbindung erstelle ich mit SQLAlchemy her. Das funktioniert gut, gibt mir auch die Werte wieder die ich erwarte wenn ich das Datum explizit in der Query angeben.
Nun habe ich damit rumgespielt, eine kleine Eingabeaufforderung zu erstellen, das Datum wird in der Deutschen Form angegeben und in das Format umgewandelt wie es in der Tabelle zu finden ist. Ich verstehe noch nicht so recht, wie ich mit der Variable, die ja nun einen String enthält, in meiner Query weiter machen kann. Lässt sich der String denn noch einmal in ein Datumsformat umwandelt?
Code: Alles auswählen
import sqlalchemy as sa
from sqlalchemy import create_engine
from sqlalchemy import text
from datetime import datetime
from sqlalchemy.sql.sqltypes import DATETIME
SERVER = 'DESKTOP-UP2PHSF\SQLEXPRESS'
DATABASE = 'kunden'
DRIVER = 'ODBC Driver 17 for SQL Server'
USERNAME = ''
PASSWORD = ''
DATABASE_CONNECTION = f'mssql://{USERNAME}:{PASSWORD}@{SERVER}/{DATABASE}?driver={DRIVER}'
engine = create_engine(DATABASE_CONNECTION)
connection = engine.connect()
usrEnter = input("Datum angeben: ")
date = datetime.strptime(usrEnter, '%d.%m.%Y')
usrEndDate = date.strftime('%Y-%m-%d')
print(type(usrEndDate))
print(usrEndDate)
datetest = '18-10-2021'
datetestdate = 2021-10-18
print(type(usrEndDate)) #string
print(type(datetest)) #string
print(type(datetestdate)) #int
print(type(date)) #datetime
with engine.connect() as conn:
EndDate = conn.execute("SELECT * FROM kunden.dbo.kunden_kundennamen WHERE EndDate = CONVERT(datetime, '18-10-2021', 104)")
for row in EndDate:
Name = row.kdname
KdNr = row.kdnr
EndDatum = row.EndDate
#print(f"Name: {row.kdname} KdNr: {row.kdnr} End Datum: {row.EndDate}")
print(KdNr, Name, EndDatum)
Meine Ausgabe die ich erhalte:
Code: Alles auswählen
Datum angeben: <class 'str'>
2021-10-18
<class 'str'>
<class 'str'>
<class 'int'>
<class 'datetime.datetime'>
2 Müller 2021-10-18
3 Busch 2021-10-18
Der Thread 'MainThread' (0x1) hat mit Code 0 (0x0) geendet.
Das Programm "python.exe" wurde mit Code 0 (0x0) beendet.
Ich danke euch schon für eure letzten Denkanstöße.
Re: MSSQL - Bestimmtes Datum auslesen
Verfasst: Freitag 18. Februar 2022, 13:55
von Juliusvanvern
Ich glaube nun hab ich es..
Code: Alles auswählen
("SELECT * FROM kunden.dbo.kunden_kundennamen WHERE EndDate =?", usrEndDate)
Ich habe die Variable immer versucht direkt in die Query mit aufzunehmen. Das hat nicht funktioniert. So geht es jedoch scheinbar.