我有一个包含80.000多边形的Shapefile,它们按照名为" OTA "的特定字段进行分组。
我想将每个Shapefile(它的属性表)转换为mdb数据库(不是个人地理数据库),其中包含一个与Shapefile同名且具有给定字段结构的表。
在我使用的代码中,我不得不加载Python 2新模块:
pypyodbc
和adodbapi
第一个模块用于为每个shapefile创建mdb文件,第二个模块用于在mdb中创建表,并使用shapefile属性表中的数据填充表。
我提出的代码如下:
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')')
执行此代码大约需要5分钟才能完成约140 mdbs的任务 如您所见,我执行了一个" INSERT INTO" shapefile的每条记录的语句。
这是正确的方式(可能是最快的)还是我应该为每个" OTA"收集所有的陈述?并一起执行它们?
答案 0 :(得分:1)
我认为没有人会为你编写你的代码,但如果你自己尝试一些VBA,并告诉我们发生了什么,什么有用,你会坚持什么,你会得到很好的回应。< / p>
说 - 首先,当你可以在mdb文件中使用VBA时,我没有看到任何使用VB6的理由。
使用DIR命令和可能的FileSystemObject循环遍历给定文件夹中的所有DBF,或者使用FileDialog对象一次选择多个文件
然后用
处理每个文件DoCmd.TransferDatabase command
TransferType:=acImport, _
DatabaseType:="dBASE III", _
DatabaseName:="your-dbf-filepath", _
ObjectType:=acTable, _
Source:="Source", _
Destination:="your-newtbldbf"
最后使用make table查询处理每个dbf导入
查看结果,看看可能需要根据前后字段类型进行更改。
然后....编辑你的帖子,让我们知道它是怎么回事
答案 1 :(得分:0)
理论上你可以通过搜索DBF文件所在的目录,将这些文件名写入表,然后循环遍历表,并为每个文件名扫描DBF中的表及其字段名/数据类型来执行此类操作。在MDB中创建这些表。您还可以从表中引入所有数据,所有数据都在一系列循环中。
理论上,你可以。
在实践中,你不能。而且你不能,因为DBF和MDB支持不兼容的不同数据类型。
我假设你可以创建一个“人行横道”表,这样对于DBF中的每个数据类型,MDB中都有一个相应的,手工挑选的数据类型,并在创建表时使用它,但是它可能要么无法导入某些数据,要么导入损坏的数据。这就是假设您可以打开DBF进行读取,就像打开MDB进行读取一样。您可以从Access内部在DBF上运行OpenDatabase吗?我甚至没有答案。
答案 2 :(得分:0)
我不建议你这样做。你这样做的原因是因为你想在从dBase / FoxBase迁移到Access时保持结构尽可能相似。但是,它们之间的文件结构不同。
如您所知,每个.DBF(“数据库文件”)文件都是一个表,.DBF文件所在的文件夹或目录构成“数据库”。使用Access,一个数据库中的所有表都在一个.MDB(“Microsoft数据库”)文件中。
如果您尝试将每个.DBF文件放在单独的.MDB文件中,那么获取.MDB文件进行交互就没有问题。 Access将不同的.MDB文件视为不同的数据库,而不是同一数据库中的不同表,并且您必须执行奇怪的操作,例如链接所有单独的数据库以获得基本的关系功能。 (大约25年前我用Paradox文件尝试了这个,它也是一个每个表一个文件的结构。我花了很长时间才决定它更容易习惯每个数据库的单文件概念。)帮自己一个忙,并将一个文件夹中的所有.DBF文件迁移到一个.MDB文件中。
至于你应该对你的代码做什么,我首先建议你使用ADO而不是DAO。但是如果你想坚持DAO,因为你一直在使用DAO,那么你需要有一个连接到dBase文件而另一个连接到Access数据库。据我所知,你没有dBase连接。我以前从未尝试过您正在做的事情,但我怀疑您是否可以使用SQL语句直接从.dbf文件中进行选择。 (但我可能错了;多年来微软已经提出了一些陌生的东西。)
它会