分析csv的第一行并在数据库中创建一个表


Parsing first line of csv and creating a table inside database

我每晚都在用PHP的cron作业下载新的csv。每个csv通常大致相同,可能在一个月内的某个晚上,一个字段是新的。我需要获取新字段并将其附加到数据库中。我不知道如何获得新领域的类型。我看到了别人关于gettype()的问题,但我不确定这是否有效,因为数据在csv中,所以当一些数据需要浮点或int时,它们不是都是字符串吗?我该如何检查类型?

第二个问题,有没有办法检查表中是否没有名称?例如,如果他们添加了一个名为foo52的新字段,而我的数据库中有foo1到foo51,有没有一种快速的方法来搜索不存在的字段,或者我必须为每个字段使用一个select语句,并在它为false时将其追加?

我的数据库使用MySQL。

谢谢你的帮助。

关于获取类型的第一个问题是简单地尝试数据本身的转换,然后查看数据是否与==比较等效。

所以,

some,data,is,123

读取数据后,您可以尝试转换为各种类型,如字符串、int等。。。然后您就可以确定数据的类型。

对于第二个问题,您可以通过以下操作获取列名:

show columns from db.table_name

然后,您可以执行一个简单的in_array来测试新列名是否已经在数据库中。

编辑:

使用array_diff可以简化从CSV中查找缺失/新列名的过程。

csv_names = get_csv_column_names();
sql_names = get_sql_column_names();
new_names = array_diff( csv_names, sql_names );

我发现parsecsv for php库对于构造CSV数据非常方便。

对于第一个问题:您可以使用is_numeric()测试它是否是数字。如果不是,则存储为字符串。如果是,请在数据库中将字段创建为数字字段。如果您愿意,您可以使用regex来检查它是日期还是您认为需要正确存储的其他数据类型(即不是默认文本)

对于第二个问题:在Postgres中获取表的字段名是通过以下查询完成的

$sql = "SELECT attname FROM pg_catalog.pg_attribute
                    WHERE attrelid =
                        (SELECT c.oid FROM pg_catalog.pg_class c LEFT JOIN pg_namespace n  ON n.oid = c.relnamespace
                            WHERE c.relname = '$this->tableName' AND n.nspname = 'public')
                        AND attnum > 0
                        AND NOT attisdropped";

对于MySQL,它应该可以通过"显示db.table_name中的列"来实现。

一旦有了字段,请使用in_array()检查它是否已经存在。。。

注意:如果CSV中的所有列已经存在,您可能需要检查它们。如果不是:为它添加一个新列。如果是,保持原样…