2016-06-17 11 views
0

Ich habe eine Shapefile mit 80.000 Polygonen, die sie nach einem bestimmten Feld namens "OTA" gruppiert sind.Shapefile zu MDB mit benutzerdefinierten Feldstruktur

Ich wollte jedes Shapefile (seine Attributtabelle) in MDB-Datenbank (nicht Personal Geodatabase) mit einer Tabelle mit dem gleichen Namen wie das Shapefile und mit einer gegebenen Feldstruktur konvertieren.
Im Code, den ich habe ich auf Python 2 neue Module zu laden hatte:
pypyodbc und adodbapi

Das erste Modul die MDB-Datei für jede Shape-Datei zu erstellen verwendet wurde und die zweite die Tabelle in der mdb zu erstellen und Füllen Sie die Tabelle mit den Daten aus der Attributtabelle der Shapefile.

Der Code kam ich mit ist die folgende:

import pypyodbc 
import adodbapi 
Folder = ur'C:\TestPO' # Folder to save the mdbs 
FD = Folder+ur'\27ALLPO.shp' # Shapefile 
Map = u'PO' # Map type 
N = u'27' # Prefecture 
OTAList = sorted(set([row[0] for row in arcpy.da.SearchCursor(FD,('OTA'))])) 
cnt = 0 
for OTAvalue in OTAList: 
    cnt += 1 
    dbname = N+OTAvalue+Map 
    pypyodbc.win_create_mdb(Folder+'\\'+dbname+'.mdb') 
    conn_str = (r"Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+Folder+"\\"+dbname+ur".mdb;") 
    conn = adodbapi.connect(conn_str) 
    crsr = conn.cursor() 
    SQL = "CREATE TABLE ["+dbname+"] ([FID] INT,[AREA] FLOAT,[PERIMETER] FLOAT,[KA_PO] VARCHAR(10),[NOMOS] VARCHAR(2),[OTA] VARCHAR(3),[KATHGORPO] VARCHAR(2),[KATHGORAL1] VARCHAR(2),[KATHGORAL2] VARCHAR(2),[LABEL_PO] VARCHAR(8),[PHOTO_45] VARCHAR(14),[PHOTO_60] VARCHAR(10),[PHOTO_PO] VARCHAR(8),[POLY_X_CO] DECIMAL(10,3),[POLY_Y_CO] DECIMAL(10,3),[PINAKOKXE] VARCHAR(11),[LANDTYPE] DECIMAL(2,0));" 
    crsr.execute(SQL) 
    conn.commit() 
    with arcpy.da.SearchCursor(FD,['FID','AREA','PERIMETER','KA_PO','NOMOS','OTA','KATHGORPO','KATHGORAL1','KATHGORAL2','LABEL_PO','PHOTO_45','PHOTO_60','PHOTO_PO','POLY_X_CO','POLY_Y_CO','PINAKOKXE','LANDTYPE'],'"OTA" = \'{}\''.format(OTAvalue)) as cur: 
     for row in cur: 
      crsr.execute("INSERT INTO "+dbname+" VALUES ("+str(row[0])+","+str(row[1])+","+str(row[2])+",'"+row[3]+"','"+row[4]+"','"+row[5]+"','"+row[6]+"','"+row[7]+"','"+row[8]+"','"+row[9]+"','"+row[10]+"','"+row[11]+"','"+row[12]+"',"+str(row[13])+","+str(row[14])+",'"+row[15]+"',"+str(row[16])+");") 
      conn.commit() 
    crsr.close() 
    conn.close() 
    print (u'«'+OTAvalue+u'» ('+str(cnt)+u'/'+str(len(OTAList))+u')') 

Ausführen dieses Code etwa 5 Minuten in Anspruch nahm die Aufgabe, für etwa 140 MEB abzuschließen.
Wie Sie sehen können, führe ich eine "INSERT INTO" -Anweisung für jeden Datensatz der Shapefile.

Ist dies der richtige Weg (und wahrscheinlich der schnellste) oder sollte ich alle Anweisungen für jeden "OTA" sammeln und sie alle zusammen ausführen?

+0

Wenn es einmal Prozedur ist, würde ich alle Dateien auf einen oder wenige MDB importieren (je nach Datengröße , 2 GB Grenze) und dann separate MDBs basierend auf importierten Tabellen erstellt, wird es einfacher als Erstellen von Tabellenstruktur mit VBA. –

Antwort

0

In der Theorie könnten Sie so etwas tun, indem Sie das Verzeichnis durchsuchen, in dem sich die DBF-Dateien befinden, diese Dateinamen in eine Tabelle schreiben, dann die Tabelle durchlaufen und für jeden Dateinamen den DBF nach Tabellen und deren Feldnamen/Datentypen scannen und erstellen Sie diese Tabellen in Ihrer MDB. Sie könnten auch alle Daten aus den Tabellen einbringen, alles innerhalb einer Reihe von Schleifen.

In der Theorie könnten Sie.

In der Praxis können Sie nicht. Und Sie können nicht, weil DBF und MDB verschiedene Datentypen unterstützen, die nicht kompatibel sind.

ich nehme an, Sie könnten einen „Zebrastreifen“ -Tabelle so erstellen, dass für jeden Datentyp in DBF gibt es eine entsprechende, von Hand gepflückt Datentyp in MDB und verwenden, wenn Sie die Tabelle erstellen, aber es wahrscheinlich geht zu Entweder können einige der Daten nicht importiert oder beschädigte Daten importiert werden. Und das setzt voraus, dass Sie einen DBF zum Lesen genauso öffnen können, wie Sie eine MDB zum Lesen öffnen können. Können Sie OpenDatabase auf einem DBF in Access ausführen? Ich habe nicht einmal die Antwort darauf.

1

Ich denke nicht, dass jemand Ihren Code für Sie schreiben wird, aber wenn Sie selbst VBA ausprobieren und uns sagen, was passiert ist und was funktioniert hat und woran Sie hängen bleiben, erhalten Sie eine großartige Antwort.

Sagen, dass - zu Beginn mit sehe ich keinen Grund, VB6 zu verwenden, wenn Sie VBA direkt in Ihrer MDB-Datei verwenden können.

Verwenden DIR-Befehl und möglicherweise Filesystem eine Schleife durch alle DBFs in einem bestimmten Ordner, oder verwenden Sie File Objekt mehrere Dateien auswählen an einem gehen

dann jede Datei bearbeiten mit

DoCmd.TransferDatabase command 
    TransferType:=acImport, _ 
    DatabaseType:="dBASE III", _ 
    DatabaseName:="your-dbf-filepath", _ 
    ObjectType:=acTable, _ 
    Source:="Source", _ 
    Destination:="your-newtbldbf" 

Schließlich jeder Prozess dbf-Import mit einer make-Tabellenabfrage

Sehen Sie sich die Ergebnisse an und sehen Sie, was möglicherweise geändert werden muss, basierend auf Feldtypen davor und danach.

Dann wird Ihr Beitrag .... bearbeiten und lassen Sie uns wissen, wie es

ging
0

Ich würde nicht empfehlen, dass Sie dies tun. Der Grund dafür ist, dass Sie die Struktur so ähnlich wie möglich bei der Migration von dBase/FoxBase zu Access beibehalten möchten. Die Dateistruktur unterscheidet sich jedoch zwischen ihnen.

Wie Sie wissen, ist jede DBF-Datei ("Database file") eine Tabelle und der Ordner oder das Verzeichnis, in dem sich die .DBF-Dateien befinden, bildet die "Datenbank". Mit Access befinden sich alle Tabellen in einer Datenbank in einer .MDB-Datei ("Microsoft Database").

Wenn Sie versuchen, jede DBF-Datei in einer separaten .MDB-Datei zu speichern, haben Sie kein Problem damit, die .MDB-Dateien zu interagieren. Access behandelt verschiedene .MDB-Dateien als verschiedene Datenbanken, nicht verschiedene Tabellen in derselben Datenbank, und Sie müssen seltsame Dinge tun, wie zum Beispiel die Verknüpfung aller separaten Datenbanken, um grundlegende relationale Funktionen zu erhalten. (Ich habe das vor etwa 25 Jahren mit Paradox-Dateien versucht, die auch eine Ein-Datei-pro-Tabelle-Struktur haben. Es dauerte nicht lange, bis ich entschied, dass es einfacher war, sich an das Ein-Datei-pro-Datenbank-Konzept zu gewöhnen .) Tun Sie sich selbst einen Gefallen und migrieren Sie alle .DBF-Dateien in einem Ordner in eine einzelne .MDB-Datei.

Was Sie mit Ihrem Code tun sollten, würde ich zuerst vorschlagen, dass Sie ADO anstelle von DAO verwenden. Wenn Sie jedoch bei DAO bleiben möchten, weil Sie es bereits verwendet haben, benötigen Sie eine Verbindung zur dBase-Datei und eine weitere zur Access-Datenbank. Soweit ich das beurteilen kann, haben Sie keine dBase-Verbindung. Ich habe noch nie versucht, was Sie bisher gemacht haben, aber ich bezweifle, dass Sie eine SQL-Anweisung verwenden können, um direkt aus einer .dbf-Datei auszuwählen, wie Sie es gerade tun. (Ich könnte falsch sein, obwohl, Microsoft hat mit seltsamere Dinge im Laufe der Jahre kommen.)

Es wäre