Я должен прочитать данные счета-фактуры из сложного файла ASCII, как бы вы защитились от будущих изменений? - PullRequest
0 голосов
/ 16 декабря 2008

Я должен прочитать файлы счетов-фактур ascii, которые структурированы действительно запутанным способом, например:

55651108 3090617.10.0806:46:32101639Example Company               Construction Company          Example Road. 9            9524 Example City

Там на самом деле есть еще кое-что, но я не хочу больше вас смущать.

Я знаю, что обречен, если клиент не может предложить лучшую структуру. Например, 30906 - это итеративное число, которое растет. 101639 - это идентификатор клиента. Пробелы между «Примерной компанией» и «Строительной компанией» имеют переменную длину. Однако в поле «Примерная компания» также могут быть пробелы переменной длины, например «Microsoft Corporation Redmond». То же самое с другими полями. Так что нет четкого способа извлечь данные из последней части.

Но это не вопрос. Меня забрали. Мой вопрос таков:

Если вход был несколько структурирован и четко определен, как бы вы защитились от будущих изменений в его структуре. Как бы вы спроектировали и внедрили читателя.

Я думал об использовании простой модели EAV в моей БД и использовании текстовых или XML-шаблонов, которые описывают ввод, имена сущностей и их значения. Я бы проанализировал файлы счетов в соответствии с шаблонами.

Ответы [ 4 ]

1 голос
/ 16 декабря 2008

"Если ввод был несколько структурирован и хорошо определен, как бы вы защитились от будущих изменений в его структуре. Как бы вы спроектировали и внедрили читатель?"

Вы должны определить макет таким образом, чтобы его можно было гибко разделить.

Вот версия Python

class Field( object ):
    def __init__( self, name, size ):
        self.name= name
        self.size = size
        self.offset= None

class Record( object ):
    def __init__( self, fieldList ):
        self.fields= fieldList
        self.fieldMap= {}
        offset= 0
        for f in self.fields: 
            f.offset= offset
            offset += f.size
            self.fieldMap[f.name]= f
    def parse( self, aLine ):
        self.buffer= aLine
    def get( self, aField ):
        fld= self.fieldMap[aField]
        return self.buffer[ fld.offset:fld.offset+fld.size+1 ]
    def __getattr__( self, aField ):
        return self.get(aField)

Теперь вы можете определять записи

myRecord= Record( 
    Field('aField',8), 
    Field('filler',1), 
    Field('another',5),
    Field('somethingElse',8),
)

Это дает вам реальный шанс выделить некоторые входные данные достаточно гибким способом.

myRecord.parse(input)
myRecord.get('aField')

Как только вы сможете анализировать, добавление конверсий - это вопрос создания подкласса Field для определения различных типов (даты, суммы и т. Д.)

0 голосов
/ 16 декабря 2008

Ваш формат файла очень похож на французский протокол, называемый Etebac , используемый между банками и их клиентами.

Это текстовый формат фиксированной ширины.

Лучшее, что вы можете сделать, это использовать какую-то функцию unpack:

$ perl -MData::Dumper -e 'print Dumper(unpack("A8 x A5 A8 A8 A6 A30 A30", "55651108 3090617.10.0806:46:32101639Example Company               Construction Company          Example Road. 9            9524 Example City"))'
$VAR1 = '55651108';
$VAR2 = '30906';
$VAR3 = '17.10.08';
$VAR4 = '06:46:32';
$VAR5 = '101639';
$VAR6 = 'Example Company';
$VAR7 = 'Construction Company';

Что вы должны сделать, это для каждого ввода проверить, что это то, что должно быть, то есть XX.XX.XX или YY: YY: YY или что оно не начинается с пробела, и прервать, если это делает.

0 голосов
/ 16 декабря 2008

У меня была бы база данных счетов-фактур с такими таблицами, как Компания, Счета-фактуры, Invoice_Items. В зависимости от сложности, хотите ли вы также записывать свои заказы, а затем связывать счета с заказами и так далее? Но я отвлекся ...

У меня была бы модель базы данных в памяти, но это само собой разумеющееся. Если бы понадобился вывод и ввод XML, у меня была бы XML-сериализация модели, если бы мне нужно было предоставлять счета в качестве данных в другом месте, и парсер SAX для его чтения. Некоторые API-интерфейсы могут сделать это тривиальным, или, может быть, вы просто хотите предоставить веб-сервис вашему хранилищу, если вы хотите, чтобы клиенты читали у вас.

Что касается чтения в текстовых файлах (а информации о них не так много - зачем их формат менять? Откуда они берутся? Вы заменяете эту систему или она продолжает работать, и Вы просто новый бэкэнд, который они подают?) Вы говорите, что число пробелов является переменным - это только потому, что формат столбцов фиксированной ширины? Я хотел бы создать читателя, который будет читать их в вашей модели, и, следовательно, схему вашей базы данных.

0 голосов
/ 16 декабря 2008

Я считаю, что шаблон, описывающий имена сущностей и типы значений, хорош. Что-то вроде «схемы» для текстового файла.

Я бы постарался максимально отделить читателя от остальной части приложения. Таким образом, вопрос на самом деле заключается в том, как определить интерфейс, который сможет приспосабливаться к изменениям в списке параметров. Это не всегда возможно, но, тем не менее, если вы полагаетесь на интерфейс для чтения данных, вы можете изменить реализацию устройства чтения, не затрагивая остальную часть системы.

...