Microsoft Access Daten auslesen und verändern

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
rosi119
User
Beiträge: 19
Registriert: Donnerstag 5. Oktober 2017, 12:25

Hallo liebe Community,

ich habe folgendes Problem...
Ich möchte bzw. muss aus einer Access Datenbank Pfade von Dateien mit deren Datei rausziehen und abspeichern und anschließnd mit einem 2 Script diese Pfade noch an passen auf ein anderes System.

Also erst mal Script 1:

Ich muss die Dateien (es sind PDF-Dateien), anhand der Pfade die in einer Access Datenbank sind herauskopieren. Das ganze soll mit Python passieren.
Also die gesamten PDF Datein in einen Ordner kopieren.
Jetzt ist die Frage wie genau geht man da for?

Funktioniert es so....

Code: Alles auswählen

import pypyodbc
import re

conn = pypyodbc.win_connect_mdb(r"Pfadmdb")

cur = conn.cursor()

cur.execute("select URL from Gefahrgut")

[0]


cur.close()
conn.commit()
conn.close()
Mit hilfe von SQL Befhelen die Datenbank durch gehen und die Pfade herauslesen?

Ich hoffe ihr könnt mir helfen.

Besten Dank schon mal.

Mit freundlichen Grüßen

Rosi119
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ja, so in etwa sollte es gehen. Wobei die tatsaechlichen Statements etc. natuerlich von deiner DB abhaengen. Du kannst dir auch das Modul shutil anschauen fuer den eigentlichen Kopiervorgang, sowie das argparse-Modul um eine Steuerung des Skripts via Kommandozeilenargumenten vornehmen zu koennen.
rosi119
User
Beiträge: 19
Registriert: Donnerstag 5. Oktober 2017, 12:25

Code: Alles auswählen

import pyodbc
import csv
import shutil
import os.path


# Einstellungen
MDB = 'pfad\Sicherheit.mdb'
DRV = '{Microsoft Access Driver (*.mdb)}'
PWD = 'pw'

# Verbindungsaufbau zur Datenbank
con = pyodbc.connect('DRIVER={};DBQ={};PWD={}'.format(DRV, MDB, PWD))
cur = con.cursor()

# SQL Anweisung zum suchen
SQL = 'SELECT URL FROM Gefahrgut;'
rows = cur.execute(SQL).fetchall()
cur.close()
con.close()
Soweit hätte ich es jetzt.
Wie lassen sich jetzt die Datein am besten kopieren die sich hinter den Pfaden verstecken?
Die sind aktuell in rows hinterlegt die Pfade.
kann shutil mehre Datein kopieren, vorallem wenn die Pfade alle in rows sind?
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Nein, da musst du schon über rows iterieren und dann shutil.copy aufrufen für jede Datei.
rosi119
User
Beiträge: 19
Registriert: Donnerstag 5. Oktober 2017, 12:25

Code: Alles auswählen

# coding: utf-8

import pyodbc
import shutil
import os

# Einstellungen
MDB = 'Pfad\Sicherheit.mdb'  # Pfad zur Datenbank
DRV = '{Microsoft Access Driver (*.mdb)}'  # Driver, welches Dateiformat
PWD = 'pw'  # Passwort für die Datenbank

# Verbindungsaufbau zur Datenbank
con = pyodbc.connect('DRIVER={};DBQ={};PWD={}'.format(DRV, MDB, PWD))
cur = con.cursor()  # Der Cursor wird verwendet um die Datensaetze durch zu gehen

# SQL Anweisung zum suchen
SQL = 'SELECT URL FROM Gefahrgut;'
rows = cur.execute(SQL).fetchall()  # fetchall sammelt alle Ergebnise

cur.close()  # Cursor beenden
con.close()  # Verbindung beenden

liste = rows  # ! Uebergibt die URL Pfade aus der SQL Abfrage

for path in liste:
    a = path[0]  # ! In der SQL Abfrage ein Tuple aber kein string, daher [0], dann faengt er mit dem 1 Objet in der tuple an
    tmp = a.split("Desktop")
    ziel = ("Pfad\Kopiert")  
    ziel = ziel + tmp[1]                                   # tmp[1], da durch Split 2 Pfadteile heraus kommen und der 2 benötigt wird

    try:
        os.makedirs(ziel.rsplit("\\", 1)[0])
    except WindowsError:
        pass                                               # Überspringt diesen Teil
    shutil.copy(a, ziel)  # Kopiert die Dateien in den Ziel Ordner
So ich habe das Problem gelöst.
Die Dateien werden kopiert und die Ordner angelegt.


Jetzt aber noch eine Frage ich muss jetzt die neu angelegte Ordner Struktur in eine Datenbank Update. Wie kann man das am besten realisieren? Bin da leider gerade etwas ratlos :x :?
Das Datenbank update wird an einem anderen Rechner gemacht, dann muss ich die Ordner Struktur ganz neu einlesen und dann an die Datenbank schicken, das es dort geändert wird oder?
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Schoen das du Fortschritte gemacht hast.

Ein paar Anmerkungen:

- die Zuweisung 'liste = rows' ist unnoetig, das ist immer noch das gleiche Objekt, nur ein neuer Name
- Deine Pfade sind nicht richtig codiert und funktionieren nur durch Zufall. \ ist ein spezielles Zeichen, mit dem sogenannte "Escapes" definiert werden. Das beruehmteste ist eine neue Zeile, \n. Wenn du also schreibst "Pfad\Sicherheit.mdb" dann klappt das nur deshalb, weil \S nichts ist. Wenn du aber "Pfad\neue-Datenbank.mdb" schreiben wuerdest (oder \t oder \m oder oder oder) - dann krachts. Darum entweder den Backslash verdoppeln, das bedeutet immer einen Backslash einzufuehren, oder sogenannte raw-strings verwenden.

Deine eigentliche Frage verstehe ich nicht so richtig, bitte erklaer das noch mal etwas umfangreicher.
rosi119
User
Beiträge: 19
Registriert: Donnerstag 5. Oktober 2017, 12:25

okay vielen Dank schon mal für deine Hilfe :).
Werde ich mir anschauen.

Zu meinem jetzigen Problem, ich habe ja eine Datenbank wo Pfade zu Dateien drin sind.
Diese Dateien habe ich mit deren Ordner kopiert, so wie in meinem Code.

Dies geschieht alles auf Rechner A.

Jetzt soll die Datenbank, wo die Pfade drin sind auf einen anderen Computer gebracht werden.
Dort sollen die Dateien die ich vorher kopiert habe auch exestieren und liegen dort dann in einem anderen Pfad.

Als Beispiel bei Rechner A war es C:\abc\def\1.pdf
Rechner B D:\FGH\def\1.pdf

Und das muss ich automatisch in der Datenbank ändern lassen.
Hoffe es ist einigermaßen verständlich....

Habe überlegt bei meinem ersten Script die Pfade die ich da raus ziehe in eine TXT Datei zu kopieren, also nur den hintern Teil der auf beiden PC´s gleich bleibt, den ich mit meinem ersten Script gesplitet habe.
Dann mach ich noch eine Input Funktion, wo man den neuen Pfad angibt also nur den Anfang.
Beispiel: Input D:\FGH\alterpfad aus der Datei
und dann mit einer SQL Anweisung die Datenbank updaten auf die neue URL.

Kann man verstehen was ich möchte :?
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@__deets__: oder man nimmt generell '/' als Pfadtrenner.

@rosi119: man darf mehr als 3 Zeichen für einen Variablennamen verwenden. Wenn Du statt MDB path_to_database nennst, brauchst Du auch keinen Kommentar. a sollte dann auch source_path heißen, und das split("Desktop") sieht sehr fragil aus. Pfade setzt man mit os.path.join zusammen, und statt ziel.rsplit nimmt man os.path.dirname.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wieso kannst du nicht die DB in dem Moment updaten in dem dieser Vorgang durchgefuehrt wird? Du kannst ja auch mehrere DBs gleichzeitig oeffnen, und aus der einen lesen und in die andere schreiben.
rosi119
User
Beiträge: 19
Registriert: Donnerstag 5. Oktober 2017, 12:25

das Problem ist das eine Script führe ich auf dem 1 PC aus da kopiert es sich alle Dateien zusammen und dann wird das 2 Script mit den Dateien verschickt und andere führen das Script aus und Packen die Dateien bei sich hin, so das ich den Pfad nicht kenne.

Daher kann ich es leider nicht direkt Updaten, da ich die neue Struktur nicht kenne.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

@rosi119: für was wird die Datenbank benutzt? Wer erwartet, dass in der Access-Datei absolute Pfade stehen? Hast Du da Einfluß drauf? Wer sind die Anwender (also innerhalb einer geschlossenen Gruppe oder Unbekannte)?
rosi119
User
Beiträge: 19
Registriert: Donnerstag 5. Oktober 2017, 12:25

Hab alles hin bekommen die Beiden Scripte laufen ohne Probleme :)

Danke für eure Hilfe :wink:
Antworten