Unknownpgr

The Real Problems Developers Face

2021-08-15 15:30:08 | English, Korean

This post was translated from Korean into English by AI.

When you work in development, you often see ideals clash with reality. This is especially true when you are developing something because someone else told you to, rather than because you wanted to do it yourself. I recently found myself working on a task that fits this situation perfectly, so I wanted to document it in a post.

2020_06_172ae1e72474f6ccd

What Do I Need to Do?

The task I have to do sounds very simple. There is some tabular data. All I have to do is upload it to a database. The database is not anything unusual, either; it is just a MySQL database.

So What Is the Problem?

Well...

There are several other detailed issues, but I cannot disclose the specific data and related information in a public place such as a blog, so I will leave the summary at that.

So How Did I Solve It?

I have not yet solved the problem of the materials stored as images, PDFs, and Hangul documents. It seems like I could at least copy and paste the tables from the Hangul documents directly into Excel, but the problem is that I use a Mac, which makes opening Hangul documents quite cumbersome. So I have put that part off for now.

As for the remaining problems, the file formats themselves are consistently CSV or XLSX; it is the structure of their contents that is inconsistent. That made them seem solvable one way or another.

After thinking about it for a long time—and I really did spend more than two days thinking about it—I first created the following simple language for defining the structure of the data. This standardizes the data's name, format, description, and so on in a form that is easy for a computer to process.

Data Name
---
AttributeName  Type  Description
...
---

Using this language, for example, a student schema with a name, student number, and department can be expressed as follows.

student
---
name       str name
number     int student number
department str department
---

Python supports multiline strings, so I simply put this into a Python file as a string. I then wrote a suitable parser that compiled schemas written in this language into Python objects. Compiling the schema above into a Python object produces the following result.

from config import Schema, Column

student = Schema(
  columns = [
    Column("name",'str','name'),
    Column("number",'int','student number'),
    Column("department",'str','department'),
  ]
)

Here, the config library and the Schema and Column classes are classes I wrote.

As you can see, the syntax above is very simple, so I implemented it using only Python's built-in string-processing functions, without a separate compiler-compiler or anything similar.

Afterward, I performed various tasks by working with the Schema and Column classes.

For example:

Those are some examples.

In particular, some attributes need to be stored in the database but will never need to be searched by their values. For such attributes, I designed the system so that giving the attribute a hyphen (-) as its name automatically groups those attributes into a single array and stores it as a JSON string. This makes the database structure much simpler and easier to manage. It also saves me the trouble of assigning names and types to dozens of unnecessary attributes.

As a result, this made the workflow much simpler. Ordinarily, I would have had to write dozens of parsers, each one reading a file and writing its contents to the database. That is really closer to manual labor than development. However, by putting a little effort into building this parser, I was able to create the following convenient workflow.

  1. Define the data structure using the syntax above
  2. Compile it to automatically generate a Python script
  3. Run the Python script to automatically initialize the database and create a new table
  4. Read the file row by row (this is also automated), then perform a small amount of exception handling
  5. Automatically generate SQL from the rows after exception handling
  6. Run it against the database, and the job is done

In particular, when generating SQL, I designed it to process multiple rows in a single query for greater efficiency. This reduces the relative cost of communicating with the database and makes it faster. I also performed some additional database tuning and increased the processing speed to 100,000 records per second.

Of the steps above, only steps 1 and 4, shown in bold, need to be performed once for each data format. Everything else is handled by shared automation scripts.

With this approach, I was able to minimize the amount of file-specific code and process the work efficiently using shared code. The project is still in progress, and I do not know whether I am allowed to make its contents public, so I cannot post the code here. However, if I receive permission to release it in the future, I plan to clean up the source code and post it as well.

Conclusion


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -