首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用dbf包编辑.dbf文件时的.dbf

使用dbf包编辑.dbf文件时的.dbf
EN

Stack Overflow用户
提问于 2017-02-09 16:18:30
回答 1查看 1.2K关注 0票数 1

最近,我从unix系统上的大气模型(HYSPLIT)中生成了几千个shapefile输出和伴随的.dbf文件。转换器txt2dbf用于将shapefile属性表(文本文件)转换为.dbf。

不幸的是,某些地方出错了(可能是分隔符/字段长度错误),因为输出.dbf文件有两个问题,如下所示:

  1. dbf的某些字段包含不应该存在的数据。这些数据已经从邻近的字段“溢出”。
  2. 添加了一个不应该存在的附加字段(它实际上来自文本文件的第一条记录"1000 201“的一部分)。

这是输出dbf中第一个记录的示例(使用dbview unix检索):

Trajnum : 1001 2 Yyyymmdd : 0111231 2 时间: 300 级别: 0。 100201:

以下是我所期望的:

Trajnum : 1000 Yyyymmdd : 20111231 时间: 2300 级别: 0。

另外,我正在研究如何防止这种情况再次发生,但理想情况下,我希望能够修复现有的.dbf文件。不幸的是,每个模型运行时都会删除文本文件,因此“修复”.dbf文件是唯一的选择。

我处理上述问题的方法如下:

  1. 使用dbf.add_fieldsdbf.write ( package dbf)将存在的字段中的信息提取到一个新变量中,然后使用dbf.delete_fields删除旧的不正确字段。
  2. 删除不需要的附加字段。

这就是我尝试过的:

代码语言:javascript
运行
复制
        with dbf.Table(db) as db:
            db.add_fields("TRAJNUMc C(4)") #create new fields
            db.add_fields("YYYYMMDDc C(8)")
            db.add_fields("TIMEc C(4)")
            for record in db: #extract data from fields
                    dbf.write(TRAJNUMc=int(str(record.Trajnum)[:4]))
                    dbf.write(YYYYMMDDc=int(str(record.Trajnum)[-1:] + str(record.Yyyymmdd)[:7]))
                    dbf.write(TIMEc=record.Yyyymmdd[-1:] + record.Time[:])
            db.delete_fields('Trajnum') # delete the incorrect fields
            db.delete_fields('Yyyymmdd')
            db.delete_fields('Time')
            db.delete_fields('1000 201') #delete the unwanted field
            db.pack()

但这会产生以下错误:

代码语言:javascript
运行
复制
dbf.ver_2.BadDataError: record data is not the correct length (should be 31, not 30)

考虑到txt2dbf转换存在明显的问题,我并不惊讶于在记录数据长度中发现一个错误。但是,这是否意味着该文件已完全损坏,并且无法提取我所需的信息(令人沮丧,因为我可以看到它的存在)?

编辑:

与其尝试编辑“坏”.dbf文件,不如1.将所需的数据提取到坏文件中的文本中,然后2.写入新的dbf。(见Ethan Furman的评论/下文的答复)。

编辑:

我需要从其中修复/恢复数据的一个错误.dbf文件的示例可以在这里找到:

https://www.dropbox.com/s/9y92f7m88a8g5y4/p0001120110.dbf?dl=0

在这里可以找到一个创建错误dbf文件的示例.txt文件:

https://www.dropbox.com/s/d0f2c0zehsyy8ab/attTEST.txt?dl=0

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-09 22:28:29

要修复数据并重新创建原始文本文件,以下代码段应该会有所帮助:

代码语言:javascript
运行
复制
import dbf

table = dbf.Table('/path/to/scramble/table.dbf')
with table:
    fixed_data = []
    for record in table:
        # convert to str/bytes while skipping delete flag
        data = record._data[1:].tostring()
        trajnum = data[:4]
        ymd = data[4:12]
        time = data [12:16]
        level = data[16:].strip()
        fixed_data.extend([trajnum, ymd, time, level])

new_file = open('repaired_data.txt', 'w')
for line in fixed_data:
    new_file.write(','.join(line) + '\n')

假设您的所有数据文件看起来都像您的示例(如果数据没有内嵌逗号,那么大的数据),那么这个粗略的代码应该有助于将您的文本文件转换为dbfs:

代码语言:javascript
运行
复制
raw_data = open('some_text_file.txt').read().split('\n')
final_table = dbf.Table(
        'dest_table.dbf',
        'trajnum C(4); yyyymmdd C(8); time C(4); level C(9)',
        )
with final_table:
    for line in raw_data:
        fields = line.split(',')
        final_table.append(tuple(fields))

# table has been populated and closed

当然,如果您想要这样做,可以使用实际日期和数字字段:

代码语言:javascript
运行
复制
# dbf string becomes
'trajnum N; yyyymmdd D; time C(4), level N'

#appending data loop becomes
    for line in raw_data:
        trajnum, ymd, time, level = line.split(',')
        trajnum = int(trajnum)
        ymd = dbf.Date(ymd[:4], ymd[4:6], ymd[6:])
        level = int(level)
        final_table.append((trajnum, ymd, time, level))
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42141714

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档