我将数据从csv复制到我的表中。但是,时间戳数据与表中的列一起复制为char(40)。现在我想修改表以将其作为时间戳,但不断收到指定输入语法错误的错误。
我相信数据的格式为ISO8601
e.g。 2016-06-03T08:00:00.020584124-04:00
我已经尝试了两个具有相同结果的SQL语句
ALTER TABLE public.data
ALTER COLUMN timestamp TYPE TIMESTAMP WITH TIME ZONE USING timestamp::TIMESTAMP WITH TIME ZONE;
ALTER TABLE public.data
ALTER COLUMN timestamp TYPE TIMESTAMPTZ USING timestamp::TIMESTAMPTZ;
更新:当我使用psycopg2的copy_from时,它会读取标题值。这就解释了为什么我在尝试更改任何char()值时遇到问题。一旦我使用copy_expert并指定csv包含头文件,我就可以使用TIMESTAMPTZ数据类型。
答案 0 :(得分:0)
您需要括号来支持冒号(def word_list_to_lower(words):
""" takes a word list with a special order (e.g. frequency)
returns a new word list all in lower case with no uniques but preserving order"""
print("word_list_to_lower")
# save orders in a dict
orders = dict()
for i in range(len(words)):
wl = words[i].lower()
# save index of first occurence of the word (prioritizing top value)
if wl not in orders:
orders[wl] = i
# contains unique lower case words, but in wrong order
words_unique = list(set(map(str.lower, words)))
# reconstruct sparse list in correct order
words_lower = [''] * len(words)
for w in words_unique:
i = orders[w]
words_lower[i] = w
# remove blank entries
words_lower = [s for s in words_lower if s!='']
return words_lower
)语法)或者您应该稍微改变它:
::
由于ALTER TABLE public.data
ALTER COLUMN "timestamp" TYPE TIMESTAMP WITH TIME ZONE
USING TIMESTAMP WITH TIME ZONE "timestamp";
是保留字,我建议您以不同的方式命名字段。
答案 1 :(得分:0)
我首先编写一个select语句,将数据正确转换为时间戳。 从数据
中选择x,y,z,to_timestamp(时间戳,'格式')定义格式的地方https://www.postgresql.org/docs/current/static/functions-formatting.html
然后只需添加一个 创建表data_new为 在您的选择查询前面
最后删除表数据并重命名新表
答案 2 :(得分:0)
首先,将列命名为#34;时间戳"这是一个非常糟糕的主意。因为它是类型的保留名称。
在USING
子句中,您可以提供一个表达式,用于计算旧列的新列值。您只需执行默认的简单赋值转换timestamp::TIMESTAMPTZ
。
应该是这样的:
ALTER TABLE public.data
ALTER COLUMN "timestamp" TYPE TIMESTAMP WITH TIME ZONE
USING to_timestamp("timestamp", 'YYYY-MM-DD HH:MI:SS');
问题是你有纳秒无法解析。您可以将其解析为微秒(添加US:YYYY-MM-DD HH:MI:SS US
),但它会给您带来不好的结果。以下是数据类型格式化函数的documentation。
如果你可以省略微秒,那就没问题了。但如果没有,您应该编写自己的解析函数并在USING
子句中使用它。
答案 3 :(得分:0)
您的ALTER
语句都可以。您认为这些值是ISO8601,但也有一些不是。您可以尝试使用regexp找到它们,例如:
select *
from public.data
where regexp_replace (timestamp, '\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d\.\d{9}-\d\d:\d\d', '') <> ''
顺便说一句,将timestamp
作为列名称是个坏主意。