码迷,mamicode.com
首页 > 其他好文 > 详细

2.表

时间:2018-08-25 16:23:16      阅读:216      评论:0      收藏:0      [点我收藏+]

标签:life   call   ati   支持   方法   size   option   lifecycle   动漫   

from odps import ODPS
o = ODPS(access_id="LTAbds3aOF3ghjek",
         secret_access_key="FezndszVvtEgcpzPUZHIT9vyWyX7W",
         project="satori",
         endpoint="http://service.odps.aliyun.com/api")

# 表是ODPS的数据存储单元

# 使用o.list_tables查看项目空间下都有哪些表
    # 返回的是一个生成器
print(list(o.list_tables()))
‘‘‘
[]
‘‘‘
# 由于我还没有建表所以是[]


# 使用o.exist_table()判断表是否存在
print(o.exist_table("emmmm"))
‘‘‘
False
‘‘‘
# 显然不存在所以为False


# 如何创建表
# 创建表可以先创建表的schema,说人话就是数据库里的列名
"""
Schema includes the columns and partitions information of a :class:`odps.models.Table`.

    There are two ways to initialize a Schema object, first is to provide columns and partitions,
    the second way is to call the class method ``from_lists``. See the examples below:

    :Example:

    >>> columns = [Column(name=‘num‘, type=‘bigint‘, comment=‘the column‘)]
    >>> partitions = [Partition(name=‘pt‘, type=‘string‘, comment=‘the partition‘)]
    >>> schema = Schema(columns=columns, partitions=partitions)
    >>> schema.columns
    [<column num, type bigint>, <partition pt, type string>]
    >>>
    >>> schema = Schema.from_lists([‘num‘], [‘bigint‘], [‘pt‘], [‘string‘])
    >>> schema.columns
    [<column num, type bigint>, <partition pt, type string>]
"""
"""
Schema包含columns和partitions信息
有两种办法去初始化Schema对象,第一种是提供columns和partitions
第二种是调用类方法from_lists
"""
from odps.models import Schema, Column, Partition
# Column主要接收三个参数
# name:列名
# type:该列存储的数据类型
# comment:注释
columns = [
    Column(name="name", type="string", comment="姓名"),
    Column(name="age", type="int", comment="年龄"),
    Column(name="anime", type="string", comment="出场动漫"),
]
partitions = [Partition(name="pt", type="string", comment="分区")]
# 传入之前设置的columns和partitions
schema = Schema(columns=columns, partitions=partitions)

# 至此,schema便设置完毕,可以来查看一下
print(schema.columns)
‘‘‘
[<column name, type string>, <column age, type int>,
 <column anime, type string>, <partition pt, type string>]
‘‘‘

print(schema.partitions)
‘‘‘
[<partition pt, type string>]
‘‘‘

# 也可以分别打印非分区字段的字段名和类型
print(schema.names)
‘‘‘
[‘name‘, ‘age‘, ‘anime‘]
‘‘‘

print(schema.types)
‘‘‘
[string, int, string]
‘‘‘


# 还可以使用from_list来设置schema,但是这样就不能对列和分区进行注释了
# 可以看一下源码
‘‘‘
@classmethod
def from_lists(cls, names, types, partition_names=None, partition_types=None):
    columns = [Column(name=name, typo=typo) for name, typo in zip(names, types)]
    if partition_names is not None and partition_types is not None:
        partitions = [Partition(name=name, typo=typo)
                      for name, typo in zip(partition_names, partition_types)]
    else:
        partitions = None
    return cls(columns=columns, partitions=partitions)
‘‘‘
‘‘‘
首先这是一个类方法,结尾的return cls(columns=columns, partitions=partitions)
表明了将会返回一个类Schema(cls)的实例对象,这种调用类方法返回实例的方式在scrapy自定义中间件也经常用到
其实cls(columns=columns, partitions=partitions)就说明了,这个from_lists本质上还是使用了我们
上面那种方法,区别就是传参变得简单了

通过columns = [Column(name=name, typo=typo) for name, typo in zip(names, types)]
partitions = [Partition(name=name, typo=typo)
                      for name, typo in zip(partition_names, partition_types)]
可以看出我们只需要按照names和types对应的顺序传参即可。
‘‘‘
schema1 = Schema.from_lists(
    names=["name", "age", "anime"],
    types=["string", "int", "string"],
    partition_names=["pt"],
    partition_types=["string"]
)
print(schema1.columns)
‘‘‘
[<column name, type string>, <column age, type int>, 
<column anime, type string>, <partition pt, type string>]
‘‘‘
# 可以看到输出结果是一样的


# 其实还有一种方式,通过from_dict
‘‘‘
@classmethod
def from_dict(cls, fields_dict, partitions_dict=None):
    fields = compat.lkeys(fields_dict)
    fields_types = compat.lvalues(fields_dict)
    partitions = compat.lkeys(partitions_dict)         if partitions_dict is not None else None
    partitions_types = compat.lvalues(partitions_dict)         if partitions_dict is not None else None

    return cls.from_lists(fields, fields_types,
                          partition_names=partitions,
                          partition_types=partitions_types)
‘‘‘
‘‘‘
同样是一个类方法,只需要传入names、types的字典即可
和from_list类似,同样无法加上注释(comment)
‘‘‘
schema2 = Schema.from_dict(fields_dict={"name": "string",
                                       "age": "int",
                                       "anime": "string"},
                          partitions_dict={"pt": "string"}
                          )
print(schema2.columns)
‘‘‘
[<column name, type string>, <column age, type int>, 
<column anime, type string>, <partition pt, type string>]
‘‘‘


# 有了schema之后,我们就可以创建表了
# 创建表使用o.create_table()创建即可
‘‘‘
def create_table(self, name, schema, project=None, comment=None, if_not_exists=False,
                lifecycle=None, shard_num=None, hub_lifecycle=None, async_=False, **kw):
name:表名
schema:上面生成的schema
project:项目名,如果不指定,那么将会是默认的项目
comment:注释
if_not_exists:如果表已经存在了,那么将不会再创建了,默认是False
lifecycle:表的生命周期,如果不指定将会使用默认的options.lifecycle,类型为int,以天为单位
shard_num:对一个表进行数据传输的并发通道的数量
hub_lifecycle:hub表中的在线数据(online data)的生命周期,类型为int,以天为单位
async_:是否异步
‘‘‘
table = o.create_table(name="girls",
                       schema=schema,
                       comment="这张表储存了我二次元老婆的信息",
                       project="satori",
                       if_not_exists=True)  # 此时名为girls的表便创建好了

# 当然也可以使用"字段名 字段类型"这种简单粗暴的方式直接创建表
table_two = o.create_table(name="girls",
                           schema="name string, age int, anime string",
                           project="satori",
                           if_not_exists=True)

# 同时在设置column的时候,也可以设置partition
# 将column和partition组合成一个元组
table_three = o.create_table(name="girls",
                             schema=("name string, age int, anime string", "pt string"),
                             project="satori",
                             if_not_exists=True)
# 由于我设置了if_not_exist=True,所以table_two和table_three不会有效果


# 检查一下,我们的表
# 获取表可以通过o.get_table()获取,传入表名和项目名即可,项目名不指定则为默认项目
‘‘‘
o.list_tables,查看项目下有哪些表
o.exist_table,查看表是否存在
o.create_table,创建表
o.get_table,获取表
通过table,而不是tables,也可以看出后三个函数只能分别对单张表进行操作
而o.list_tables可以一次性查看多张表,所以table加了s
‘‘‘
girls = o.get_table(name="girls", project="satori")
print(girls.schema)  # 查看girls表的列名以及对应类型
‘‘‘
odps.Schema {
  name      string      # 姓名
  age       bigint      # 年龄
  anime     string      # 出场动漫
}
Partitions {
  pt        string      # 分区
}
‘‘‘
# 因此也说明了我们表创建成功了
# 也可以查看其它的属性
print(girls.lifecycle)
‘‘‘
-1
‘‘‘
# 由于我们创建表的时候,没有指定,所以是-1,也就是不会自动清除

#查看表的创建时间
print(girls.creation_time)
‘‘‘
2018-08-25 15:04:16
‘‘‘

# 查看表是不是虚拟视图
print(girls.is_virtual_view)
‘‘‘
False
‘‘‘

# 查看表的大小,我们只是创建了表还没往里面塞数据
print(girls.size)  # 0

# 对该表的注释
print(girls.comment)
‘‘‘
这张表储存了我二次元老婆的信息
‘‘‘

print(girls.schema.columns)
‘‘‘
[<column name, type string>, <column age, type bigint>, 
<column anime, type string>, <partition pt, type string>]
‘‘‘

# girls是一个字典,说明我们也可以像操作字典一样获取相应的属性
print(girls.schema["name"])
‘‘‘
<column name, type string>
‘‘‘

# 获取相应字段的注释信息
print(girls.schema["anime"].comment)
‘‘‘
出场动漫
‘‘‘

‘‘‘
在未经过设置的情况下,
创建表时只允许使用 bigint、double、decimal、string、datetime、boolean、map 和 array 类型
如果你使用的是位于公共云上的服务,或者支持 tinyint、struct 等新类型,
可以设置 options.sql.use_odps2_extension = True 打开这些类型的支持,
from odps import options
options.sql.use_odps2_extension = True
table = o.create_table(‘my_new_table‘, ‘cat smallint, content struct<title:varchar(100), body string>‘)
‘‘‘

# 同步表更新
‘‘‘
有的时候,一个表可能被别的程序做了更新,比如schema有了变化
此时可以调用reload方法来进行更新
table.reload()
‘‘‘

  

 

2.表

标签:life   call   ati   支持   方法   size   option   lifecycle   动漫   

原文地址:https://www.cnblogs.com/traditional/p/9534338.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!