crown


Namecrown JSON
Version 0.3.1 PyPI version JSON
download
home_pagehttps://github.com/machine-w/crown
Summarycrown is a simple and small ORM for Time Series Database (TSDB) tdengine(taos), making it easy to learn and intuitive to use.
upload_time2023-07-09 03:29:22
maintainer
docs_urlNone
authormachine-w
requires_python>=3
license
keywords orm taos tdengine tsdb time series database connector python
VCS
bugtrack_url
requirements requests
Travis-CI No Travis.
coveralls test coverage No coveralls.
            crown
======

crown 是一个轻量级的针对时序数据(TSDB)TDengine的ORM库。 

* 需要python 3.0版本以上
* 0.1.7版本在tdengine 2版本测试通过
* 0.3.0版本在tdengine 3版本测试通过
* 解决mac操作系统下没有原生python连接器的问题
* 极大的降低了python程序员使用TDengine技术门槛
* 可以方便的将数据转换到numpy与pandas
* 目前使用TDengine的restful接口连接数据库,以后将提供原生接口引擎可供选择(目前原生接口无法在mac系统上使用)

安装
----------------------

大多数情况下,可以通过pip,轻松安装最新版本:

.. code-block:: console

    pip install crown


还可以通过git安装,项目地址: https://github.com/machine-w/crown

使用方法:

.. code-block:: console

    git clone https://github.com/machine-w/crown.git
    cd crowm
    python setup.py install


使用文档
------------------------

建立数据库与删除数据库:

.. code-block:: python

    from crown import *

    DATABASENAME = 'taos_test'
    HOST = 'localhost'
    PORT = 6041
    # 默认端口 6041,默认用户名:root,默认密码:taosdata
    db = TdEngineDatabase(DATABASENAME,host=HOST) #新建数据库对象
    # db.connect()  # 尝试连接数据库,如果库不存在,则自动建库。
    # print(db.databases) #连接数据库db对象后会自动获取全部数据库信息,以字典的形式保存在属性databases中。
    # 如不使用默认值,可以如下传入参数
    # db = TdEngineDatabase(DATABASENAME,host=HOST,port=PORT,user='yourusername',passwd='yourpassword')
    db.create_database(safe=True)  #建库指令。 (safe:如果库存在,则跳过建库指令。)
    # db.create_database(safe=True,keep= 100,comp=0,replica=1,quorum=2,blocks=115) #可选字段:建库时配置数据库参数,具体字段含义请参考tdengine文档。
    db.drop_database(safe=True) #删库指令 (safe:如果库不存在,则跳过删库指令。)

修改数据库参数:

.. code-block:: python

    db.alter_database(keep= 120,comp=1,replica=1,quorum=1,blocks=156) #同建库可选字段。

执行sql语句:

.. code-block:: python

    #可以通过数据库对象直接执行sql语句,语句规则与TDengine restful接口要求一致。
    res = db.raw_sql('select c1,c2 from taos_test.member1')
    print(res,res.head,res.rowcount) #返回的对象为二维数据。res.head属性为数组对象,保存每一行数据的代表的列名。res.rowcount属性保存返回行数。
    # res: [[1.2,2.2],[1.3,2.1],[1.5,2.0],[1.6,2.1]]
    # res.head: ['c1','c2']
    # res.rowcount: 4

打印执行的sql语句:

.. code-block:: python

    Meter1.select().one()
    print(db.curSql) #可以通过db对象的curSql属性获取当前执行的原始sql语句

模型定义:

.. code-block:: python

    from crown import *

    DATABASENAME = 'taos_test'
    HOST = 'localhost'
    db = TdEngineDatabase(DATABASENAME,host=HOST) #新建数据库对象
    db.connect()  #尝试连接数据库,如果库不存在,则自动建库。
    # print(db.databases) #连接数据库db对象后会自动获取全部数据库信息,以字典的形式保存在属性databases中。

    # 表模型类继承自Model类,每个模型类对应数据库中的一张表,模型类中定义的每个Field,对应表中的一列
    class Meter1(Model):
        cur = FloatField(db_column='c1')
        curInt = IntegerField(db_column='c2')
        curDouble = DoubleField(db_column='c3')
        desc = BinaryField(db_column='des')

        class Meta: #Meta子类中定义模型类的配置信息
            database = db #指定表所使用的数据库
            db_table = 'meter1' #指定表名

    # 可选择的全部Field类型如下,类型与Tdengine支持的数据类型一一对应
    class AllField(Model):
        name_float = FloatField(column_name='nf1') #可选项:指定列名
        name_double = DoubleField()
        name_bigint = BigIntegerField()
        name_int = IntegerField()
        name_smallint = SmallIntegerField()
        name_tinyint = TinyIntegerField()
        name_nchar = NCharField(max_length=59,db_column='n1')
        name_binary = BinaryField(max_length=3)
        name_bool = BooleanField()
        dd = PrimaryKeyField() # 如果定义了主键列,则使用主键列作为主键,如果没有定义,则默认“ts”为主键。
        birthday = DateTimeField()
        class Meta:
            database = db
            db_table = 'all_field'

主键定义:

.. code-block:: python

    #定义主键方式1 
    #不定义主键,系统默认主键:“ts”
    class TestPri(Model):
        cur = FloatField(db_column='c1')
        class Meta:
            database = db
    res = TestPri.describe_table() #获取表结构信息
    print(res[0][0]) # 结果: “ts”

    #定义主键方式2
    class TestPri(Model):
        cur = FloatField(db_column='c1')
        timeline = PrimaryKeyField() #定义主键列,主键名设置为列名
        class Meta:
            database = db
    res = TestPri.describe_table()
    print(res[0][0]) # 结果: “timeline”

     #定义主键方式3
    class TestPri(Model):
        cur = FloatField(db_column='c1')
        class Meta:
            database = db
            primary_key = 'timeline' # Meta中定主键名称
    res = TestPri.describe_table()
    print(res[0][0]) # 结果: “timeline”
    


建表、删表、检查表是否存在:

.. code-block:: python

    Meter1.create_table(safe=True) #建表 safe:如果表存在,则跳过建表指令。命令运行成功放回True,失败raise错误
    # db.create_table(Meter1,safe=True) #通过数据库对象建表,功能同上
    Meter1.drop_table(safe=True) #删表 safe:如果表不存在,则跳过删表指令。命令运行成功放回True,失败raise错误
    # db.drop_table(Meter1,safe=True) #通过数据库对象删表,功能同上
    Meter1.table_exists() #查看表是否存在,存在返回True,不存在返回:False

动态建表:

除了使用定义模型类的方式建表外,还提供了动态定义字段建表的功能。

.. code-block:: python

    #可以使用Model类的类方法dynamic_create_table方法动态建表,第一个参数为表名,然后需要指定数据库,与是否安全建表。
    # 关键词参数可以任意多个,指定表中的字段。
    Meter_dynamic= Model.dynamic_create_table('meterD',database=db,safe=True,test1 = FloatField(db_column='t1'),test2 = IntegerField(db_column='t2'))
    # 函数返回的对象为Model类对象。使用方法与静态继承的模型类相同。
    Meter_dynamic.table_exists()
    Meter_dynamic.drop_table()

从表名建立对应的model类:

数据库中已有的数据库表,可以通过已知的表名建立对应的model类。

.. code-block:: python

    nodeTable = Model.model_from_table('node_10',db) # node_10为数据表的表名
    res = nodeTable.select().one() # 从表名新建的类和静态建立的类,使用方法完全一致
    
    
动态建立的或从数据库分析得到的model对象,可以直接使用列名作为属性名进行查询操作。

.. code-block:: python


    res = nodeTable.select(nodeTable.c1)where(nodeTable.c1 > 1).all() # 直接使用列名
    res = nodeTable.select(nodeTable.c1)where(FloatField(db_column='c1') > 1).all() # 也可以使用field对象作为字段检索条件(多使用于列名为动态值的时候)
    # 直接使用列名,查看结果
    for item in res:
        print(item.c1)

插入数据:

.. code-block:: python

    #方法一
    for i in range(1,101):
        #使用模型类实例化的每个对象对应数据表中的每一行,可以通过传入属性参数的方式给每一列赋值
        m = Meter1(cur = 1/i,curInt=i,curDouble=1/i+10,desc='g1',ts= datetime.datetime.now() - datetime.timedelta(seconds=(102-i)))
        #使用对象的save方法将数据存入数据库
        m.save()
    print(Meter1.select().count()) # 结果:100
    #方法二
    for i in range(1,11):
        #也可以直接使用模型类的insert方法插入数据。
        Meter1.insert(cur = 1/i,curInt=i,curDouble=1/i+10,desc='g1',ts= datetime.datetime.now() - datetime.timedelta(seconds=(12-i)))
    print(Meter1.select().count()) # 结果:100
    #如果不传入时间属性,则会以当前时刻为默认值传入
    Meter1.insert(cur = 1/i,curInt=i,curDouble=1/i+10,desc='g1')
    m = Meter1(cur = 1/i,curInt=i,curDouble=1/i+10,desc='g1')
    m.save()

查询单条数据:

.. code-block:: python

    #获取一条数据
    #使用select()类方法获取查询字段(参数留空表示取全部字段),然后可以链式使用one方法获取第一条数据
    res = Meter1.select().one()
    print(res.desc,res.curDouble,res.curInt,res.cur,res.ts)

    #select函数中可以选择要读取的字段
    res = Meter1.select(Meter1.cur,Meter1.desc).one()
    print(res.desc,res.curDouble,res.curInt,res.cur,res.ts)

    #select函数中可以使用Model的类方法f()和fc()获取字符串形式的属性名与列名对应Field对象
    res = Meter1.select(Meter1.f('cur'),Meter1.fc('c3'),Meter1.desc).one()
    print(res.desc,res.curDouble,res.curInt,res.fc('c3'),res.f('cur'),res.ts)

查询全部数据:

.. code-block:: python

    #获取一条数据
    #使用select()类方法获取查询字段(参数留空表示取全部字段),然后可以链式使用all方法获取全部数据
    res_all = Meter1.select().all()
    for res in res_all:
        print(res.desc,res.curDouble,res.curInt,res.cur,res.ts)

    #select函数中可以选择要读取的字段
    res_all = Meter1.select(Meter1.cur,Meter1.desc).all()
    for res in res_all:
        print(res.desc,res.curDouble,res.curInt,res.cur,res.ts)

虽然TDengine提供了很多聚合和统计函数,但是把时序数据导入numpy或pandas等数据分析组件中进行处理的情况也是很常见的操作。
下面介绍如何通过crown把结果数据导入numpy和pandas

读取数据到numpy:

.. code-block:: python

    #通过all_raw函数可以获取二维数组格式的数据查询结果。结果每列代表的标题保存在结果对象的head属性中。
    raw_results = Meter1.select(Meter1.cur,Meter1.curInt,Meter1.curDouble).all_raw()
    #可以很方便的将结果转换为numpy数组对象
    np_data = np.array(raw_results)
    print(np_data)
    print(raw_results.head)

读取数据到pandas:

.. code-block:: python

    raw_results = Meter1.select().all_raw()
    #使用以下方法,可以轻松的将数据导入pandas,并且使用时间点作为index,使用返回的数据标题作为列名。
    pd_data = pd.DataFrame(raw_results,columns=raw_results.head).set_index('ts')
    print(pd_data)

选择列四则运算:

.. code-block:: python

    #使用select()类方法获取查询字段时,可以返回某列或多列间的值加、减、乘、除、取余计算结果(+ - * / %)
    res_all = Meter1.select((Meter1.curDouble+Meter1.cur),Meter1.ts).all()
    for res in res_all:
        print(res.get(Meter1.curDouble+Meter1.cur),res.ts) #返回的结果对象可以用get方法获取原始计算式结果

    #字段别名
    res_all = Meter1.select(((Meter1.curDouble+Meter1.cur)*Meter1.curDouble).alias('new_name'),Meter1.ts).all() #给运算式起别名(不仅运算式,其他放在select函数中的任何属性都可以使用别名)
    for res in res_all:
        print(res.new_name,res.ts) #使用别名获取运算结果

where查询条件:

.. code-block:: python

    #可以在select函数后链式调用where函数进行条件限
    one_time =datetime.datetime.now() - datetime.timedelta(hours=10)
    ress = Meter1.select().where(Meter1.ts > one_time).all()
    #限定条件可以使用 > < == >= <= != and or ! 等。字符类型的字段可以使用 % 作为模糊查询(相当于like)
    # 逻辑操作符号 |: 或 &:与 ~:非。(注意:做逻辑操作符号的表达式需要用括号括起来)
    ress = Meter1.select().where((Meter1.cur > 0) | (Meter1.desc % 'g%')).all()
    #where函数可以接收任意多参数,每个参数为一个限定条件,参数条件之间为"与"的关系。
    ress = Meter1.select().where(Meter1.cur > 0, Meter1.ts > one_time, Meter1.desc % '%1').all()

分页与limit:

.. code-block:: python

    #可以在select函数后链式调用paginate函数进行分页操作,以下例子为取第6页 每页5条数据。
    ress_1 = Meter1.select().paginate(6,page_size=5).all()
    ress_2 = Meter1.select().paginate(6).all() #默认page_size为20
    #可以在select函数后链式调用limit函数和offset函数条数限制和定位操作。
    ress_3 = Meter1.select().limit(2).offset(5).all()
    ress_4 = Meter1.select().limit(2).all()

排序(目前tdengine只支持主键排序):

.. code-block:: python

    #可以在select函数后链式调用desc或者asc函数进行时间轴的正序或者倒序查询
    res = Meter1.select().desc().one()
    #定义模型类的时候定义默认排序方法
    class Meter1(Model):
        cur = FloatField(db_column='c1')
        curInt = IntegerField(db_column='c2')
        curDouble = DoubleField(db_column='c3')
        desc = BinaryField(db_column='des')
        dd = PrimaryKeyField().desc() #可以在定义主键的时候调用field的desc或asc方法定义默认排序
        class Meta:
            # order_by= ['-dd'] #也可以在元数据类中定义‘-dd’代表倒序‘dd’ 代表正序
            database = db

去重 :

.. code-block:: python

    #可以在select函数后链式调用distinct函数对返回的数据列进行去重复操作
    res = Meter1.select().distinct().all()

聚合函数:

.. code-block:: python

    #count
    count = Meter1.select().count() #统计行数
    print(count) # 结果: 100
    count = Meter1.select().count(Meter1.desc) #统计指定列非空行数
    print(count) # 结果: 90
    #avg(sum,stddev,min,max,first,last,last_row,spread使用方法与avg相同)
    avg1 = Meter1.select().avg(Meter1.cur,Meter1.curDouble.alias('aa')) #可以同时获取多列,并且可以使用别名
    print(avg1.get(Meter1.cur.avg()),avg1.aa) #打印统计结果
    #twa 必须配合where函数,且必须选择时间段
    twa1 = Meter1.select().where(Meter1.ts > datetime.datetime(2020, 11, 19, 15, 9, 12, 946118),Meter1.ts < datetime.datetime.now()).twa(Meter1.cur,Meter1.curDouble.alias('aa'))
    print(twa1.get(Meter1.cur.twa()),avg1.aa) #打印统计结果

    #diff
    diffs = Meter1.select().diff(Meter1.curInt.alias('aa')) #diff目前只可以聚合一个属性。
    for diff1 in diffs:
        print(diff1.aa,diff1.ts) # 时间点数据同时返回

    #top(bottom函数使用方式相同)
    tops = Meter1.select().top(Meter1.cur,3,alias='aa') # top函数需要提供要统计的属性,行数,以及别名
    for top1 in tops:
        print(top1.aa,top1.ts) # 时间点数据同时返回
    tops = Meter1.select().top(Meter1.cur,3) # 可以不指定别名
    for top1 in tops:
        print(top1.get(Meter1.cur.top(3))) #不指定别名,需用使用get方法获取属性

    #percentile (apercentile函数使用方式相同) 
    percentile1 = Meter1.select().percentile((Meter1.cur,1,'aa'),(Meter1.curDouble,2)) #每个属性参数为一个元组(数组),分别定义要统计的属性,P值(P值取值范围0≤P≤100),可选别名。
    print(percentile1.aa)
    print(percentile1.get(Meter1.curDouble.percentile(2)))#不指定别名,需用使用get方法获取属性

    #leastsquares
    leastsquares1 = Meter1.select().leastsquares((Meter1.cur,1,1,'aa'),(Meter1.curDouble,2,2)) #每个属性参数为一个元组(数组),分别定义要统计的属性,start_val(自变量初始值),step_val(自变量的步长值),可选别名。
    print(leastsquares1.aa) # 结果: {slop:-0.001595, intercept:0.212111}
    print(leastsquares1.get(Meter1.curDouble.leastsquares(2,2))) #不指定别名,需用使用get方法获取属性

group_by分组查询:

.. code-block:: python

    # 可以在链式调用中加入group_by函数指定要分组的字段。然后在select函数中指定要分组统计的聚合函数(支持的聚合函数有:count、avg、sum 、stddev、leastsquares、percentile、min、max、first、last)
    groups= Meter1.select(Meter1.desc,Meter1.curInt.avg().alias('intavg'),Meter1.cur.count().alias('curcount')).group_by(Meter1.desc).all()
    for group in groups:
        print(group.desc)
        if group.desc == 'g1':
            # assert group.get(Meter1.curInt.count()) == 10
            assert group.intavg == 5.5
            assert group.curcount == 10
        if group.desc == 'g2':
            assert group.intavg == 10.5
            assert group.curcount == 20

时间维度聚合interval:

.. code-block:: python

    # 可以使用interval函数调用TDengine时间纬度聚合功能,使用方法如下 时间间隔与offset参数参考TDengine文档(s:秒,m:分钟,h:小时)。fill参数可选字符串(NONE | PREV | NULL | LINEAR)或者任意数值,例如:fill=1.2将会以固定值填充。
    results= Meter1.select(Meter1.cur.avg().alias('aa'),Meter1.cur.first().alias('bb')).where(Meter1.ts > (datetime.datetime.now()-datetime.timedelta(days=1))).interval('10s',fill='PREV',offset='1m').all()
    for result in results:
        print(result.aa,result.bb)

join查询:

目前并支持多表join查询,需要多表查询的情况请使用raw_sql函数,执行原始sql语句。以后的版本会补充此功能。


超级表定义:

.. code-block:: python

    # 超级表模型类继承自SuperModel类
    class Meters(SuperModel):
        cur = FloatField(db_column='c1')
        curInt = IntegerField(db_column='c2')
        curDouble = DoubleField(db_column='c3')
        desc = BinaryField(db_column='des')
        class Meta:
            database = db
            db_table = 'meters'
            # Meta类中定义的Field,为超级表的标签
            location = BinaryField(max_length=30)
            groupid = IntegerField(db_column='gid')

超级表的建表、删表、检查表是否存在:

.. code-block:: python

    Meters.create_table(safe=True) #建表 safe:如果表存在,则跳过建表指令。命令运行成功放回True,失败raise错误
    # db.create_table(Meters,safe=True) #通过数据库对象建表,功能同上
    Meters.drop_table(safe=True) #删表 safe:如果表不存在,则跳过删表指令。命令运行成功放回True,失败raise错误
    # db.drop_table(Meters,safe=True) #通过数据库对象删表,功能同上
    Meters.supertable_exists() #查看表是否存在,存在返回True,不存在返回:False

超级表动态建表:

超级表除了使用定义模型类的方式建表外,也提供了动态定义字段建表的功能。

.. code-block:: python

    #可以使用SuperModel类的类方法dynamic_create_table方法动态建表,第一个参数为表名,然后需要指定数据库,与是否安全建表
    # 需要额外提供tags参数,参数值为一个字典(使用方法如下例),设置超级表所有的标签。
    # 关键词参数可以任意多个,指定表中的字段。
    Meter_dynamic= SuperModel.dynamic_create_table('meterSD',database=db,safe=True,tags={'gid':IntegerField(db_column='tag1')},test1 = FloatField(db_column='t1'),test2 = IntegerField(db_column='t2'))
    # 函数返回的对象为SuperModel类对象。使用方法与静态继承的模型类相同。
    Meter_dynamic.supertable_exists()
    Meter_dynamic.drop_table()

从表名建立对应的supermodel类:

数据库中已有的数据库超级表,可以通过已知的表名建立对应的supermodel类。

.. code-block:: python

    sTable = SuperModel.supermodel_from_table('rule_10',db) # rule_10为数据表的表名
    res = sTable.select().one() # 从表名新建的类和静态建立的类,使用方法完全一致

从超级表建立子表:

.. code-block:: python

    SonTable_d3 = Meters.create_son_table('d3',location='beijing',groupid=3) #生成字表模型类的同时,自动在数据库中建表。

    SonTable_d3.table_exists() # SonTable_d3的使用方法和继承自Modle类的模型类一样。可以进行插入与查询操作
    # m = SonTable_d3(cur = 65.8,curInt=10,curDouble=1.1,desc='g1',ts = datetime.datetime.now())
    # m.save()

新增标签:

.. code-block:: python

    # 使用add_tags方法,可以给超级表新建多个标签。每个参数可以是一个Field对象(必须指定db_column属性)
    Meters.add_tags(IntegerField(db_column='add_tag_1'),IntegerField(db_column='add_tag_4'),BinaryField(max_length=30,db_column='add_tag_5'))

删除标签:

.. code-block:: python

    # 使用drop_tag方法可以删除超级表的标签,参数名为标签名,一次只能删除一个标签
    Meters.drop_tag('add_tag_2')

修改标签名:

.. code-block:: python

    # 使用change_tag_name方法可以修改超级表的标签名,参数名为要修改的标签名,和新的标签名。(注意:此方法只修改对应超级表的标签名,并不修改类的属性名)
    Meters.change_tag_name('add_tag_1','add_tag_2')


修改子表标签值:

.. code-block:: python

    TableT = Meters.create_son_table('d3_insert',location='beijing',gid=3)
    # 子表可以通过change_tag_value方法修改自己的标签值。
    TableT.change_tag_value(location='tianjin',gid = 6)



关于debug信息打印:

如需查看crown调用tdengine引擎时执行的sql语句和返回的原始数据。只需要配置crown模块的logger记录器的日志输出级别为debug即可。

.. code-block:: python

    import logging
    from crown import logger

    logger.setLevel(logging.DEBUG) #配置logger对象,即可输出执行debug信息

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/machine-w/crown",
    "name": "crown",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3",
    "maintainer_email": "",
    "keywords": "orm,taos,TDengine,TSDB,Time Series Database,connector,python",
    "author": "machine-w",
    "author_email": "steve2008.ma@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/79/17/b34840d2ebff9d5b2d045b0fb32d83e19d62043b7607460e7df42ac0881f/crown-0.3.1.tar.gz",
    "platform": null,
    "description": "crown\n======\n\ncrown \u662f\u4e00\u4e2a\u8f7b\u91cf\u7ea7\u7684\u9488\u5bf9\u65f6\u5e8f\u6570\u636e\uff08TSDB\uff09TDengine\u7684ORM\u5e93\u3002 \n\n* \u9700\u8981python 3.0\u7248\u672c\u4ee5\u4e0a\n* 0.1.7\u7248\u672c\u5728tdengine 2\u7248\u672c\u6d4b\u8bd5\u901a\u8fc7\n* 0.3.0\u7248\u672c\u5728tdengine 3\u7248\u672c\u6d4b\u8bd5\u901a\u8fc7\n* \u89e3\u51b3mac\u64cd\u4f5c\u7cfb\u7edf\u4e0b\u6ca1\u6709\u539f\u751fpython\u8fde\u63a5\u5668\u7684\u95ee\u9898\n* \u6781\u5927\u7684\u964d\u4f4e\u4e86python\u7a0b\u5e8f\u5458\u4f7f\u7528TDengine\u6280\u672f\u95e8\u69db\n* \u53ef\u4ee5\u65b9\u4fbf\u7684\u5c06\u6570\u636e\u8f6c\u6362\u5230numpy\u4e0epandas\n* \u76ee\u524d\u4f7f\u7528TDengine\u7684restful\u63a5\u53e3\u8fde\u63a5\u6570\u636e\u5e93\uff0c\u4ee5\u540e\u5c06\u63d0\u4f9b\u539f\u751f\u63a5\u53e3\u5f15\u64ce\u53ef\u4f9b\u9009\u62e9\uff08\u76ee\u524d\u539f\u751f\u63a5\u53e3\u65e0\u6cd5\u5728mac\u7cfb\u7edf\u4e0a\u4f7f\u7528\uff09\n\n\u5b89\u88c5\n----------------------\n\n\u5927\u591a\u6570\u60c5\u51b5\u4e0b\uff0c\u53ef\u4ee5\u901a\u8fc7pip,\u8f7b\u677e\u5b89\u88c5\u6700\u65b0\u7248\u672c\uff1a\n\n.. code-block:: console\n\n    pip install crown\n\n\n\u8fd8\u53ef\u4ee5\u901a\u8fc7git\u5b89\u88c5\uff0c\u9879\u76ee\u5730\u5740\uff1a https://github.com/machine-w/crown\n\n\u4f7f\u7528\u65b9\u6cd5:\n\n.. code-block:: console\n\n    git clone https://github.com/machine-w/crown.git\n    cd crowm\n    python setup.py install\n\n\n\u4f7f\u7528\u6587\u6863\n------------------------\n\n\u5efa\u7acb\u6570\u636e\u5e93\u4e0e\u5220\u9664\u6570\u636e\u5e93:\n\n.. code-block:: python\n\n    from crown import *\n\n    DATABASENAME = 'taos_test'\n    HOST = 'localhost'\n    PORT = 6041\n    # \u9ed8\u8ba4\u7aef\u53e3 6041\uff0c\u9ed8\u8ba4\u7528\u6237\u540d\uff1aroot,\u9ed8\u8ba4\u5bc6\u7801\uff1ataosdata\n    db = TdEngineDatabase(DATABASENAME,host=HOST) #\u65b0\u5efa\u6570\u636e\u5e93\u5bf9\u8c61\n    # db.connect()  # \u5c1d\u8bd5\u8fde\u63a5\u6570\u636e\u5e93\uff0c\u5982\u679c\u5e93\u4e0d\u5b58\u5728\uff0c\u5219\u81ea\u52a8\u5efa\u5e93\u3002\n    # print(db.databases) #\u8fde\u63a5\u6570\u636e\u5e93db\u5bf9\u8c61\u540e\u4f1a\u81ea\u52a8\u83b7\u53d6\u5168\u90e8\u6570\u636e\u5e93\u4fe1\u606f\uff0c\u4ee5\u5b57\u5178\u7684\u5f62\u5f0f\u4fdd\u5b58\u5728\u5c5e\u6027databases\u4e2d\u3002\n    # \u5982\u4e0d\u4f7f\u7528\u9ed8\u8ba4\u503c\uff0c\u53ef\u4ee5\u5982\u4e0b\u4f20\u5165\u53c2\u6570\n    # db = TdEngineDatabase(DATABASENAME,host=HOST,port=PORT,user='yourusername',passwd='yourpassword')\n    db.create_database(safe=True)  #\u5efa\u5e93\u6307\u4ee4\u3002 \uff08safe\uff1a\u5982\u679c\u5e93\u5b58\u5728\uff0c\u5219\u8df3\u8fc7\u5efa\u5e93\u6307\u4ee4\u3002\uff09\n    # db.create_database(safe=True,keep= 100,comp=0,replica=1,quorum=2,blocks=115) #\u53ef\u9009\u5b57\u6bb5\uff1a\u5efa\u5e93\u65f6\u914d\u7f6e\u6570\u636e\u5e93\u53c2\u6570\uff0c\u5177\u4f53\u5b57\u6bb5\u542b\u4e49\u8bf7\u53c2\u8003tdengine\u6587\u6863\u3002\n    db.drop_database(safe=True) #\u5220\u5e93\u6307\u4ee4 \uff08safe\uff1a\u5982\u679c\u5e93\u4e0d\u5b58\u5728\uff0c\u5219\u8df3\u8fc7\u5220\u5e93\u6307\u4ee4\u3002\uff09\n\n\u4fee\u6539\u6570\u636e\u5e93\u53c2\u6570:\n\n.. code-block:: python\n\n    db.alter_database(keep= 120,comp=1,replica=1,quorum=1,blocks=156) #\u540c\u5efa\u5e93\u53ef\u9009\u5b57\u6bb5\u3002\n\n\u6267\u884csql\u8bed\u53e5:\n\n.. code-block:: python\n\n    #\u53ef\u4ee5\u901a\u8fc7\u6570\u636e\u5e93\u5bf9\u8c61\u76f4\u63a5\u6267\u884csql\u8bed\u53e5\uff0c\u8bed\u53e5\u89c4\u5219\u4e0eTDengine restful\u63a5\u53e3\u8981\u6c42\u4e00\u81f4\u3002\n    res = db.raw_sql('select c1,c2 from taos_test.member1')\n    print(res,res.head,res.rowcount) #\u8fd4\u56de\u7684\u5bf9\u8c61\u4e3a\u4e8c\u7ef4\u6570\u636e\u3002res.head\u5c5e\u6027\u4e3a\u6570\u7ec4\u5bf9\u8c61\uff0c\u4fdd\u5b58\u6bcf\u4e00\u884c\u6570\u636e\u7684\u4ee3\u8868\u7684\u5217\u540d\u3002res.rowcount\u5c5e\u6027\u4fdd\u5b58\u8fd4\u56de\u884c\u6570\u3002\n    # res: [[1.2,2.2],[1.3,2.1],[1.5,2.0],[1.6,2.1]]\n    # res.head: ['c1','c2']\n    # res.rowcount: 4\n\n\u6253\u5370\u6267\u884c\u7684sql\u8bed\u53e5:\n\n.. code-block:: python\n\n    Meter1.select().one()\n    print(db.curSql) #\u53ef\u4ee5\u901a\u8fc7db\u5bf9\u8c61\u7684curSql\u5c5e\u6027\u83b7\u53d6\u5f53\u524d\u6267\u884c\u7684\u539f\u59cbsql\u8bed\u53e5\n\n\u6a21\u578b\u5b9a\u4e49:\n\n.. code-block:: python\n\n    from crown import *\n\n    DATABASENAME = 'taos_test'\n    HOST = 'localhost'\n    db = TdEngineDatabase(DATABASENAME,host=HOST) #\u65b0\u5efa\u6570\u636e\u5e93\u5bf9\u8c61\n    db.connect()  #\u5c1d\u8bd5\u8fde\u63a5\u6570\u636e\u5e93\uff0c\u5982\u679c\u5e93\u4e0d\u5b58\u5728\uff0c\u5219\u81ea\u52a8\u5efa\u5e93\u3002\n    # print(db.databases) #\u8fde\u63a5\u6570\u636e\u5e93db\u5bf9\u8c61\u540e\u4f1a\u81ea\u52a8\u83b7\u53d6\u5168\u90e8\u6570\u636e\u5e93\u4fe1\u606f\uff0c\u4ee5\u5b57\u5178\u7684\u5f62\u5f0f\u4fdd\u5b58\u5728\u5c5e\u6027databases\u4e2d\u3002\n\n    # \u8868\u6a21\u578b\u7c7b\u7ee7\u627f\u81eaModel\u7c7b\uff0c\u6bcf\u4e2a\u6a21\u578b\u7c7b\u5bf9\u5e94\u6570\u636e\u5e93\u4e2d\u7684\u4e00\u5f20\u8868\uff0c\u6a21\u578b\u7c7b\u4e2d\u5b9a\u4e49\u7684\u6bcf\u4e2aField\uff0c\u5bf9\u5e94\u8868\u4e2d\u7684\u4e00\u5217\n    class Meter1(Model):\n        cur = FloatField(db_column='c1')\n        curInt = IntegerField(db_column='c2')\n        curDouble = DoubleField(db_column='c3')\n        desc = BinaryField(db_column='des')\n\n        class Meta: #Meta\u5b50\u7c7b\u4e2d\u5b9a\u4e49\u6a21\u578b\u7c7b\u7684\u914d\u7f6e\u4fe1\u606f\n            database = db #\u6307\u5b9a\u8868\u6240\u4f7f\u7528\u7684\u6570\u636e\u5e93\n            db_table = 'meter1' #\u6307\u5b9a\u8868\u540d\n\n    # \u53ef\u9009\u62e9\u7684\u5168\u90e8Field\u7c7b\u578b\u5982\u4e0b\uff0c\u7c7b\u578b\u4e0eTdengine\u652f\u6301\u7684\u6570\u636e\u7c7b\u578b\u4e00\u4e00\u5bf9\u5e94\n    class AllField(Model):\n        name_float = FloatField(column_name='nf1') #\u53ef\u9009\u9879\uff1a\u6307\u5b9a\u5217\u540d\n        name_double = DoubleField()\n        name_bigint = BigIntegerField()\n        name_int = IntegerField()\n        name_smallint = SmallIntegerField()\n        name_tinyint = TinyIntegerField()\n        name_nchar = NCharField(max_length=59,db_column='n1')\n        name_binary = BinaryField(max_length=3)\n        name_bool = BooleanField()\n        dd = PrimaryKeyField() # \u5982\u679c\u5b9a\u4e49\u4e86\u4e3b\u952e\u5217\uff0c\u5219\u4f7f\u7528\u4e3b\u952e\u5217\u4f5c\u4e3a\u4e3b\u952e\uff0c\u5982\u679c\u6ca1\u6709\u5b9a\u4e49\uff0c\u5219\u9ed8\u8ba4\u201cts\u201d\u4e3a\u4e3b\u952e\u3002\n        birthday = DateTimeField()\n        class Meta:\n            database = db\n            db_table = 'all_field'\n\n\u4e3b\u952e\u5b9a\u4e49\uff1a\n\n.. code-block:: python\n\n    #\u5b9a\u4e49\u4e3b\u952e\u65b9\u5f0f1 \n    #\u4e0d\u5b9a\u4e49\u4e3b\u952e\uff0c\u7cfb\u7edf\u9ed8\u8ba4\u4e3b\u952e\uff1a\u201cts\u201d\n    class TestPri(Model):\n        cur = FloatField(db_column='c1')\n        class Meta:\n            database = db\n    res = TestPri.describe_table() #\u83b7\u53d6\u8868\u7ed3\u6784\u4fe1\u606f\n    print(res[0][0]) # \u7ed3\u679c: \u201cts\u201d\n\n    #\u5b9a\u4e49\u4e3b\u952e\u65b9\u5f0f2\n    class TestPri(Model):\n        cur = FloatField(db_column='c1')\n        timeline = PrimaryKeyField() #\u5b9a\u4e49\u4e3b\u952e\u5217\uff0c\u4e3b\u952e\u540d\u8bbe\u7f6e\u4e3a\u5217\u540d\n        class Meta:\n            database = db\n    res = TestPri.describe_table()\n    print(res[0][0]) # \u7ed3\u679c: \u201ctimeline\u201d\n\n     #\u5b9a\u4e49\u4e3b\u952e\u65b9\u5f0f3\n    class TestPri(Model):\n        cur = FloatField(db_column='c1')\n        class Meta:\n            database = db\n            primary_key = 'timeline' # Meta\u4e2d\u5b9a\u4e3b\u952e\u540d\u79f0\n    res = TestPri.describe_table()\n    print(res[0][0]) # \u7ed3\u679c: \u201ctimeline\u201d\n    \n\n\n\u5efa\u8868\u3001\u5220\u8868\u3001\u68c0\u67e5\u8868\u662f\u5426\u5b58\u5728\uff1a\n\n.. code-block:: python\n\n    Meter1.create_table(safe=True) #\u5efa\u8868 safe\uff1a\u5982\u679c\u8868\u5b58\u5728\uff0c\u5219\u8df3\u8fc7\u5efa\u8868\u6307\u4ee4\u3002\u547d\u4ee4\u8fd0\u884c\u6210\u529f\u653e\u56deTrue,\u5931\u8d25raise\u9519\u8bef\n    # db.create_table(Meter1,safe=True) #\u901a\u8fc7\u6570\u636e\u5e93\u5bf9\u8c61\u5efa\u8868\uff0c\u529f\u80fd\u540c\u4e0a\n    Meter1.drop_table(safe=True) #\u5220\u8868 safe\uff1a\u5982\u679c\u8868\u4e0d\u5b58\u5728\uff0c\u5219\u8df3\u8fc7\u5220\u8868\u6307\u4ee4\u3002\u547d\u4ee4\u8fd0\u884c\u6210\u529f\u653e\u56deTrue,\u5931\u8d25raise\u9519\u8bef\n    # db.drop_table(Meter1,safe=True) #\u901a\u8fc7\u6570\u636e\u5e93\u5bf9\u8c61\u5220\u8868\uff0c\u529f\u80fd\u540c\u4e0a\n    Meter1.table_exists() #\u67e5\u770b\u8868\u662f\u5426\u5b58\u5728\uff0c\u5b58\u5728\u8fd4\u56deTrue,\u4e0d\u5b58\u5728\u8fd4\u56de\uff1aFalse\n\n\u52a8\u6001\u5efa\u8868\uff1a\n\n\u9664\u4e86\u4f7f\u7528\u5b9a\u4e49\u6a21\u578b\u7c7b\u7684\u65b9\u5f0f\u5efa\u8868\u5916\uff0c\u8fd8\u63d0\u4f9b\u4e86\u52a8\u6001\u5b9a\u4e49\u5b57\u6bb5\u5efa\u8868\u7684\u529f\u80fd\u3002\n\n.. code-block:: python\n\n    #\u53ef\u4ee5\u4f7f\u7528Model\u7c7b\u7684\u7c7b\u65b9\u6cd5dynamic_create_table\u65b9\u6cd5\u52a8\u6001\u5efa\u8868\uff0c\u7b2c\u4e00\u4e2a\u53c2\u6570\u4e3a\u8868\u540d\uff0c\u7136\u540e\u9700\u8981\u6307\u5b9a\u6570\u636e\u5e93\uff0c\u4e0e\u662f\u5426\u5b89\u5168\u5efa\u8868\u3002\n    # \u5173\u952e\u8bcd\u53c2\u6570\u53ef\u4ee5\u4efb\u610f\u591a\u4e2a\uff0c\u6307\u5b9a\u8868\u4e2d\u7684\u5b57\u6bb5\u3002\n    Meter_dynamic= Model.dynamic_create_table('meterD',database=db,safe=True,test1 = FloatField(db_column='t1'),test2 = IntegerField(db_column='t2'))\n    # \u51fd\u6570\u8fd4\u56de\u7684\u5bf9\u8c61\u4e3aModel\u7c7b\u5bf9\u8c61\u3002\u4f7f\u7528\u65b9\u6cd5\u4e0e\u9759\u6001\u7ee7\u627f\u7684\u6a21\u578b\u7c7b\u76f8\u540c\u3002\n    Meter_dynamic.table_exists()\n    Meter_dynamic.drop_table()\n\n\u4ece\u8868\u540d\u5efa\u7acb\u5bf9\u5e94\u7684model\u7c7b\uff1a\n\n\u6570\u636e\u5e93\u4e2d\u5df2\u6709\u7684\u6570\u636e\u5e93\u8868\uff0c\u53ef\u4ee5\u901a\u8fc7\u5df2\u77e5\u7684\u8868\u540d\u5efa\u7acb\u5bf9\u5e94\u7684model\u7c7b\u3002\n\n.. code-block:: python\n\n    nodeTable = Model.model_from_table('node_10',db) # node_10\u4e3a\u6570\u636e\u8868\u7684\u8868\u540d\n    res = nodeTable.select().one() # \u4ece\u8868\u540d\u65b0\u5efa\u7684\u7c7b\u548c\u9759\u6001\u5efa\u7acb\u7684\u7c7b\uff0c\u4f7f\u7528\u65b9\u6cd5\u5b8c\u5168\u4e00\u81f4\n    \n    \n\u52a8\u6001\u5efa\u7acb\u7684\u6216\u4ece\u6570\u636e\u5e93\u5206\u6790\u5f97\u5230\u7684model\u5bf9\u8c61\uff0c\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\u5217\u540d\u4f5c\u4e3a\u5c5e\u6027\u540d\u8fdb\u884c\u67e5\u8be2\u64cd\u4f5c\u3002\n\n.. code-block:: python\n\n\n    res = nodeTable.select(nodeTable.c1)where(nodeTable.c1 > 1).all() # \u76f4\u63a5\u4f7f\u7528\u5217\u540d\n    res = nodeTable.select(nodeTable.c1)where(FloatField(db_column='c1') > 1).all() # \u4e5f\u53ef\u4ee5\u4f7f\u7528field\u5bf9\u8c61\u4f5c\u4e3a\u5b57\u6bb5\u68c0\u7d22\u6761\u4ef6\uff08\u591a\u4f7f\u7528\u4e8e\u5217\u540d\u4e3a\u52a8\u6001\u503c\u7684\u65f6\u5019\uff09\n    # \u76f4\u63a5\u4f7f\u7528\u5217\u540d,\u67e5\u770b\u7ed3\u679c\n    for item in res:\n        print(item.c1)\n\n\u63d2\u5165\u6570\u636e\uff1a\n\n.. code-block:: python\n\n    #\u65b9\u6cd5\u4e00\n    for i in range(1,101):\n        #\u4f7f\u7528\u6a21\u578b\u7c7b\u5b9e\u4f8b\u5316\u7684\u6bcf\u4e2a\u5bf9\u8c61\u5bf9\u5e94\u6570\u636e\u8868\u4e2d\u7684\u6bcf\u4e00\u884c\uff0c\u53ef\u4ee5\u901a\u8fc7\u4f20\u5165\u5c5e\u6027\u53c2\u6570\u7684\u65b9\u5f0f\u7ed9\u6bcf\u4e00\u5217\u8d4b\u503c\n        m = Meter1(cur = 1/i,curInt=i,curDouble=1/i+10,desc='g1',ts= datetime.datetime.now() - datetime.timedelta(seconds=(102-i)))\n        #\u4f7f\u7528\u5bf9\u8c61\u7684save\u65b9\u6cd5\u5c06\u6570\u636e\u5b58\u5165\u6570\u636e\u5e93\n        m.save()\n    print(Meter1.select().count()) # \u7ed3\u679c\uff1a100\n    #\u65b9\u6cd5\u4e8c\n    for i in range(1,11):\n        #\u4e5f\u53ef\u4ee5\u76f4\u63a5\u4f7f\u7528\u6a21\u578b\u7c7b\u7684insert\u65b9\u6cd5\u63d2\u5165\u6570\u636e\u3002\n        Meter1.insert(cur = 1/i,curInt=i,curDouble=1/i+10,desc='g1',ts= datetime.datetime.now() - datetime.timedelta(seconds=(12-i)))\n    print(Meter1.select().count()) # \u7ed3\u679c\uff1a100\n    #\u5982\u679c\u4e0d\u4f20\u5165\u65f6\u95f4\u5c5e\u6027\uff0c\u5219\u4f1a\u4ee5\u5f53\u524d\u65f6\u523b\u4e3a\u9ed8\u8ba4\u503c\u4f20\u5165\n    Meter1.insert(cur = 1/i,curInt=i,curDouble=1/i+10,desc='g1')\n    m = Meter1(cur = 1/i,curInt=i,curDouble=1/i+10,desc='g1')\n    m.save()\n\n\u67e5\u8be2\u5355\u6761\u6570\u636e\uff1a\n\n.. code-block:: python\n\n    #\u83b7\u53d6\u4e00\u6761\u6570\u636e\n    #\u4f7f\u7528select()\u7c7b\u65b9\u6cd5\u83b7\u53d6\u67e5\u8be2\u5b57\u6bb5\uff08\u53c2\u6570\u7559\u7a7a\u8868\u793a\u53d6\u5168\u90e8\u5b57\u6bb5\uff09\uff0c\u7136\u540e\u53ef\u4ee5\u94fe\u5f0f\u4f7f\u7528one\u65b9\u6cd5\u83b7\u53d6\u7b2c\u4e00\u6761\u6570\u636e\n    res = Meter1.select().one()\n    print(res.desc,res.curDouble,res.curInt,res.cur,res.ts)\n\n    #select\u51fd\u6570\u4e2d\u53ef\u4ee5\u9009\u62e9\u8981\u8bfb\u53d6\u7684\u5b57\u6bb5\n    res = Meter1.select(Meter1.cur,Meter1.desc).one()\n    print(res.desc,res.curDouble,res.curInt,res.cur,res.ts)\n\n    #select\u51fd\u6570\u4e2d\u53ef\u4ee5\u4f7f\u7528Model\u7684\u7c7b\u65b9\u6cd5f()\u548cfc()\u83b7\u53d6\u5b57\u7b26\u4e32\u5f62\u5f0f\u7684\u5c5e\u6027\u540d\u4e0e\u5217\u540d\u5bf9\u5e94Field\u5bf9\u8c61\n    res = Meter1.select(Meter1.f('cur'),Meter1.fc('c3'),Meter1.desc).one()\n    print(res.desc,res.curDouble,res.curInt,res.fc('c3'),res.f('cur'),res.ts)\n\n\u67e5\u8be2\u5168\u90e8\u6570\u636e\uff1a\n\n.. code-block:: python\n\n    #\u83b7\u53d6\u4e00\u6761\u6570\u636e\n    #\u4f7f\u7528select()\u7c7b\u65b9\u6cd5\u83b7\u53d6\u67e5\u8be2\u5b57\u6bb5\uff08\u53c2\u6570\u7559\u7a7a\u8868\u793a\u53d6\u5168\u90e8\u5b57\u6bb5\uff09\uff0c\u7136\u540e\u53ef\u4ee5\u94fe\u5f0f\u4f7f\u7528all\u65b9\u6cd5\u83b7\u53d6\u5168\u90e8\u6570\u636e\n    res_all = Meter1.select().all()\n    for res in res_all:\n        print(res.desc,res.curDouble,res.curInt,res.cur,res.ts)\n\n    #select\u51fd\u6570\u4e2d\u53ef\u4ee5\u9009\u62e9\u8981\u8bfb\u53d6\u7684\u5b57\u6bb5\n    res_all = Meter1.select(Meter1.cur,Meter1.desc).all()\n    for res in res_all:\n        print(res.desc,res.curDouble,res.curInt,res.cur,res.ts)\n\n\u867d\u7136TDengine\u63d0\u4f9b\u4e86\u5f88\u591a\u805a\u5408\u548c\u7edf\u8ba1\u51fd\u6570\uff0c\u4f46\u662f\u628a\u65f6\u5e8f\u6570\u636e\u5bfc\u5165numpy\u6216pandas\u7b49\u6570\u636e\u5206\u6790\u7ec4\u4ef6\u4e2d\u8fdb\u884c\u5904\u7406\u7684\u60c5\u51b5\u4e5f\u662f\u5f88\u5e38\u89c1\u7684\u64cd\u4f5c\u3002\n\u4e0b\u9762\u4ecb\u7ecd\u5982\u4f55\u901a\u8fc7crown\u628a\u7ed3\u679c\u6570\u636e\u5bfc\u5165numpy\u548cpandas\n\n\u8bfb\u53d6\u6570\u636e\u5230numpy\uff1a\n\n.. code-block:: python\n\n    #\u901a\u8fc7all_raw\u51fd\u6570\u53ef\u4ee5\u83b7\u53d6\u4e8c\u7ef4\u6570\u7ec4\u683c\u5f0f\u7684\u6570\u636e\u67e5\u8be2\u7ed3\u679c\u3002\u7ed3\u679c\u6bcf\u5217\u4ee3\u8868\u7684\u6807\u9898\u4fdd\u5b58\u5728\u7ed3\u679c\u5bf9\u8c61\u7684head\u5c5e\u6027\u4e2d\u3002\n    raw_results = Meter1.select(Meter1.cur,Meter1.curInt,Meter1.curDouble).all_raw()\n    #\u53ef\u4ee5\u5f88\u65b9\u4fbf\u7684\u5c06\u7ed3\u679c\u8f6c\u6362\u4e3anumpy\u6570\u7ec4\u5bf9\u8c61\n    np_data = np.array(raw_results)\n    print(np_data)\n    print(raw_results.head)\n\n\u8bfb\u53d6\u6570\u636e\u5230pandas\uff1a\n\n.. code-block:: python\n\n    raw_results = Meter1.select().all_raw()\n    #\u4f7f\u7528\u4ee5\u4e0b\u65b9\u6cd5\uff0c\u53ef\u4ee5\u8f7b\u677e\u7684\u5c06\u6570\u636e\u5bfc\u5165pandas,\u5e76\u4e14\u4f7f\u7528\u65f6\u95f4\u70b9\u4f5c\u4e3aindex,\u4f7f\u7528\u8fd4\u56de\u7684\u6570\u636e\u6807\u9898\u4f5c\u4e3a\u5217\u540d\u3002\n    pd_data = pd.DataFrame(raw_results,columns=raw_results.head).set_index('ts')\n    print(pd_data)\n\n\u9009\u62e9\u5217\u56db\u5219\u8fd0\u7b97\uff1a\n\n.. code-block:: python\n\n    #\u4f7f\u7528select()\u7c7b\u65b9\u6cd5\u83b7\u53d6\u67e5\u8be2\u5b57\u6bb5\u65f6\uff0c\u53ef\u4ee5\u8fd4\u56de\u67d0\u5217\u6216\u591a\u5217\u95f4\u7684\u503c\u52a0\u3001\u51cf\u3001\u4e58\u3001\u9664\u3001\u53d6\u4f59\u8ba1\u7b97\u7ed3\u679c\uff08+ - * / %\uff09\n    res_all = Meter1.select((Meter1.curDouble+Meter1.cur),Meter1.ts).all()\n    for res in res_all:\n        print(res.get(Meter1.curDouble+Meter1.cur),res.ts) #\u8fd4\u56de\u7684\u7ed3\u679c\u5bf9\u8c61\u53ef\u4ee5\u7528get\u65b9\u6cd5\u83b7\u53d6\u539f\u59cb\u8ba1\u7b97\u5f0f\u7ed3\u679c\n\n    #\u5b57\u6bb5\u522b\u540d\n    res_all = Meter1.select(((Meter1.curDouble+Meter1.cur)*Meter1.curDouble).alias('new_name'),Meter1.ts).all() #\u7ed9\u8fd0\u7b97\u5f0f\u8d77\u522b\u540d\uff08\u4e0d\u4ec5\u8fd0\u7b97\u5f0f\uff0c\u5176\u4ed6\u653e\u5728select\u51fd\u6570\u4e2d\u7684\u4efb\u4f55\u5c5e\u6027\u90fd\u53ef\u4ee5\u4f7f\u7528\u522b\u540d\uff09\n    for res in res_all:\n        print(res.new_name,res.ts) #\u4f7f\u7528\u522b\u540d\u83b7\u53d6\u8fd0\u7b97\u7ed3\u679c\n\nwhere\u67e5\u8be2\u6761\u4ef6\uff1a\n\n.. code-block:: python\n\n    #\u53ef\u4ee5\u5728select\u51fd\u6570\u540e\u94fe\u5f0f\u8c03\u7528where\u51fd\u6570\u8fdb\u884c\u6761\u4ef6\u9650\n    one_time =datetime.datetime.now() - datetime.timedelta(hours=10)\n    ress = Meter1.select().where(Meter1.ts > one_time).all()\n    #\u9650\u5b9a\u6761\u4ef6\u53ef\u4ee5\u4f7f\u7528 > < == >= <= != and or ! \u7b49\u3002\u5b57\u7b26\u7c7b\u578b\u7684\u5b57\u6bb5\u53ef\u4ee5\u4f7f\u7528 % \u4f5c\u4e3a\u6a21\u7cca\u67e5\u8be2\uff08\u76f8\u5f53\u4e8elike\uff09\n    # \u903b\u8f91\u64cd\u4f5c\u7b26\u53f7 |: \u6216 &\uff1a\u4e0e ~\uff1a\u975e\u3002\uff08\u6ce8\u610f\uff1a\u505a\u903b\u8f91\u64cd\u4f5c\u7b26\u53f7\u7684\u8868\u8fbe\u5f0f\u9700\u8981\u7528\u62ec\u53f7\u62ec\u8d77\u6765\uff09\n    ress = Meter1.select().where((Meter1.cur > 0) | (Meter1.desc % 'g%')).all()\n    #where\u51fd\u6570\u53ef\u4ee5\u63a5\u6536\u4efb\u610f\u591a\u53c2\u6570\uff0c\u6bcf\u4e2a\u53c2\u6570\u4e3a\u4e00\u4e2a\u9650\u5b9a\u6761\u4ef6\uff0c\u53c2\u6570\u6761\u4ef6\u4e4b\u95f4\u4e3a\"\u4e0e\"\u7684\u5173\u7cfb\u3002\n    ress = Meter1.select().where(Meter1.cur > 0, Meter1.ts > one_time, Meter1.desc % '%1').all()\n\n\u5206\u9875\u4e0elimit\uff1a\n\n.. code-block:: python\n\n    #\u53ef\u4ee5\u5728select\u51fd\u6570\u540e\u94fe\u5f0f\u8c03\u7528paginate\u51fd\u6570\u8fdb\u884c\u5206\u9875\u64cd\u4f5c\uff0c\u4ee5\u4e0b\u4f8b\u5b50\u4e3a\u53d6\u7b2c6\u9875 \u6bcf\u98755\u6761\u6570\u636e\u3002\n    ress_1 = Meter1.select().paginate(6,page_size=5).all()\n    ress_2 = Meter1.select().paginate(6).all() #\u9ed8\u8ba4page_size\u4e3a20\n    #\u53ef\u4ee5\u5728select\u51fd\u6570\u540e\u94fe\u5f0f\u8c03\u7528limit\u51fd\u6570\u548coffset\u51fd\u6570\u6761\u6570\u9650\u5236\u548c\u5b9a\u4f4d\u64cd\u4f5c\u3002\n    ress_3 = Meter1.select().limit(2).offset(5).all()\n    ress_4 = Meter1.select().limit(2).all()\n\n\u6392\u5e8f\uff08\u76ee\u524dtdengine\u53ea\u652f\u6301\u4e3b\u952e\u6392\u5e8f\uff09\uff1a\n\n.. code-block:: python\n\n    #\u53ef\u4ee5\u5728select\u51fd\u6570\u540e\u94fe\u5f0f\u8c03\u7528desc\u6216\u8005asc\u51fd\u6570\u8fdb\u884c\u65f6\u95f4\u8f74\u7684\u6b63\u5e8f\u6216\u8005\u5012\u5e8f\u67e5\u8be2\n    res = Meter1.select().desc().one()\n    #\u5b9a\u4e49\u6a21\u578b\u7c7b\u7684\u65f6\u5019\u5b9a\u4e49\u9ed8\u8ba4\u6392\u5e8f\u65b9\u6cd5\n    class Meter1(Model):\n        cur = FloatField(db_column='c1')\n        curInt = IntegerField(db_column='c2')\n        curDouble = DoubleField(db_column='c3')\n        desc = BinaryField(db_column='des')\n        dd = PrimaryKeyField().desc() #\u53ef\u4ee5\u5728\u5b9a\u4e49\u4e3b\u952e\u7684\u65f6\u5019\u8c03\u7528field\u7684desc\u6216asc\u65b9\u6cd5\u5b9a\u4e49\u9ed8\u8ba4\u6392\u5e8f\n        class Meta:\n            # order_by= ['-dd'] #\u4e5f\u53ef\u4ee5\u5728\u5143\u6570\u636e\u7c7b\u4e2d\u5b9a\u4e49\u2018-dd\u2019\u4ee3\u8868\u5012\u5e8f\u2018dd\u2019 \u4ee3\u8868\u6b63\u5e8f\n            database = db\n\n\u53bb\u91cd \uff1a\n\n.. code-block:: python\n\n    #\u53ef\u4ee5\u5728select\u51fd\u6570\u540e\u94fe\u5f0f\u8c03\u7528distinct\u51fd\u6570\u5bf9\u8fd4\u56de\u7684\u6570\u636e\u5217\u8fdb\u884c\u53bb\u91cd\u590d\u64cd\u4f5c\n    res = Meter1.select().distinct().all()\n\n\u805a\u5408\u51fd\u6570\uff1a\n\n.. code-block:: python\n\n    #count\n    count = Meter1.select().count() #\u7edf\u8ba1\u884c\u6570\n    print(count) # \u7ed3\u679c\uff1a 100\n    count = Meter1.select().count(Meter1.desc) #\u7edf\u8ba1\u6307\u5b9a\u5217\u975e\u7a7a\u884c\u6570\n    print(count) # \u7ed3\u679c\uff1a 90\n    #avg\uff08sum,stddev,min,max,first,last,last_row,spread\u4f7f\u7528\u65b9\u6cd5\u4e0eavg\u76f8\u540c\uff09\n    avg1 = Meter1.select().avg(Meter1.cur,Meter1.curDouble.alias('aa')) #\u53ef\u4ee5\u540c\u65f6\u83b7\u53d6\u591a\u5217\uff0c\u5e76\u4e14\u53ef\u4ee5\u4f7f\u7528\u522b\u540d\n    print(avg1.get(Meter1.cur.avg()),avg1.aa) #\u6253\u5370\u7edf\u8ba1\u7ed3\u679c\n    #twa \u5fc5\u987b\u914d\u5408where\u51fd\u6570\uff0c\u4e14\u5fc5\u987b\u9009\u62e9\u65f6\u95f4\u6bb5\n    twa1 = Meter1.select().where(Meter1.ts > datetime.datetime(2020, 11, 19, 15, 9, 12, 946118),Meter1.ts < datetime.datetime.now()).twa(Meter1.cur,Meter1.curDouble.alias('aa'))\n    print(twa1.get(Meter1.cur.twa()),avg1.aa) #\u6253\u5370\u7edf\u8ba1\u7ed3\u679c\n\n    #diff\n    diffs = Meter1.select().diff(Meter1.curInt.alias('aa')) #diff\u76ee\u524d\u53ea\u53ef\u4ee5\u805a\u5408\u4e00\u4e2a\u5c5e\u6027\u3002\n    for diff1 in diffs:\n        print(diff1.aa,diff1.ts) # \u65f6\u95f4\u70b9\u6570\u636e\u540c\u65f6\u8fd4\u56de\n\n    #top(bottom\u51fd\u6570\u4f7f\u7528\u65b9\u5f0f\u76f8\u540c)\n    tops = Meter1.select().top(Meter1.cur,3,alias='aa') # top\u51fd\u6570\u9700\u8981\u63d0\u4f9b\u8981\u7edf\u8ba1\u7684\u5c5e\u6027\uff0c\u884c\u6570\uff0c\u4ee5\u53ca\u522b\u540d\n    for top1 in tops:\n        print(top1.aa,top1.ts) # \u65f6\u95f4\u70b9\u6570\u636e\u540c\u65f6\u8fd4\u56de\n    tops = Meter1.select().top(Meter1.cur,3) # \u53ef\u4ee5\u4e0d\u6307\u5b9a\u522b\u540d\n    for top1 in tops:\n        print(top1.get(Meter1.cur.top(3))) #\u4e0d\u6307\u5b9a\u522b\u540d\uff0c\u9700\u7528\u4f7f\u7528get\u65b9\u6cd5\u83b7\u53d6\u5c5e\u6027\n\n    #percentile (apercentile\u51fd\u6570\u4f7f\u7528\u65b9\u5f0f\u76f8\u540c) \n    percentile1 = Meter1.select().percentile((Meter1.cur,1,'aa'),(Meter1.curDouble,2)) #\u6bcf\u4e2a\u5c5e\u6027\u53c2\u6570\u4e3a\u4e00\u4e2a\u5143\u7ec4\uff08\u6570\u7ec4\uff09\uff0c\u5206\u522b\u5b9a\u4e49\u8981\u7edf\u8ba1\u7684\u5c5e\u6027\uff0cP\u503c\uff08P\u503c\u53d6\u503c\u8303\u56f40\u2264P\u2264100\uff09\uff0c\u53ef\u9009\u522b\u540d\u3002\n    print(percentile1.aa)\n    print(percentile1.get(Meter1.curDouble.percentile(2)))#\u4e0d\u6307\u5b9a\u522b\u540d\uff0c\u9700\u7528\u4f7f\u7528get\u65b9\u6cd5\u83b7\u53d6\u5c5e\u6027\n\n    #leastsquares\n    leastsquares1 = Meter1.select().leastsquares((Meter1.cur,1,1,'aa'),(Meter1.curDouble,2,2)) #\u6bcf\u4e2a\u5c5e\u6027\u53c2\u6570\u4e3a\u4e00\u4e2a\u5143\u7ec4\uff08\u6570\u7ec4\uff09\uff0c\u5206\u522b\u5b9a\u4e49\u8981\u7edf\u8ba1\u7684\u5c5e\u6027\uff0cstart_val(\u81ea\u53d8\u91cf\u521d\u59cb\u503c)\uff0cstep_val(\u81ea\u53d8\u91cf\u7684\u6b65\u957f\u503c)\uff0c\u53ef\u9009\u522b\u540d\u3002\n    print(leastsquares1.aa) # \u7ed3\u679c\uff1a {slop:-0.001595, intercept:0.212111}\n    print(leastsquares1.get(Meter1.curDouble.leastsquares(2,2))) #\u4e0d\u6307\u5b9a\u522b\u540d\uff0c\u9700\u7528\u4f7f\u7528get\u65b9\u6cd5\u83b7\u53d6\u5c5e\u6027\n\ngroup_by\u5206\u7ec4\u67e5\u8be2\uff1a\n\n.. code-block:: python\n\n    # \u53ef\u4ee5\u5728\u94fe\u5f0f\u8c03\u7528\u4e2d\u52a0\u5165group_by\u51fd\u6570\u6307\u5b9a\u8981\u5206\u7ec4\u7684\u5b57\u6bb5\u3002\u7136\u540e\u5728select\u51fd\u6570\u4e2d\u6307\u5b9a\u8981\u5206\u7ec4\u7edf\u8ba1\u7684\u805a\u5408\u51fd\u6570\uff08\u652f\u6301\u7684\u805a\u5408\u51fd\u6570\u6709\uff1acount\u3001avg\u3001sum \u3001stddev\u3001leastsquares\u3001percentile\u3001min\u3001max\u3001first\u3001last\uff09\n    groups= Meter1.select(Meter1.desc,Meter1.curInt.avg().alias('intavg'),Meter1.cur.count().alias('curcount')).group_by(Meter1.desc).all()\n    for group in groups:\n        print(group.desc)\n        if group.desc == 'g1':\n            # assert group.get(Meter1.curInt.count()) == 10\n            assert group.intavg == 5.5\n            assert group.curcount == 10\n        if group.desc == 'g2':\n            assert group.intavg == 10.5\n            assert group.curcount == 20\n\n\u65f6\u95f4\u7ef4\u5ea6\u805a\u5408interval:\n\n.. code-block:: python\n\n    # \u53ef\u4ee5\u4f7f\u7528interval\u51fd\u6570\u8c03\u7528TDengine\u65f6\u95f4\u7eac\u5ea6\u805a\u5408\u529f\u80fd,\u4f7f\u7528\u65b9\u6cd5\u5982\u4e0b \u65f6\u95f4\u95f4\u9694\u4e0eoffset\u53c2\u6570\u53c2\u8003TDengine\u6587\u6863\uff08s:\u79d2\uff0cm:\u5206\u949f\uff0ch:\u5c0f\u65f6\uff09\u3002fill\u53c2\u6570\u53ef\u9009\u5b57\u7b26\u4e32(NONE | PREV | NULL | LINEAR)\u6216\u8005\u4efb\u610f\u6570\u503c,\u4f8b\u5982\uff1afill=1.2\u5c06\u4f1a\u4ee5\u56fa\u5b9a\u503c\u586b\u5145\u3002\n    results= Meter1.select(Meter1.cur.avg().alias('aa'),Meter1.cur.first().alias('bb')).where(Meter1.ts > (datetime.datetime.now()-datetime.timedelta(days=1))).interval('10s',fill='PREV',offset='1m').all()\n    for result in results:\n        print(result.aa,result.bb)\n\njoin\u67e5\u8be2\uff1a\n\n\u76ee\u524d\u5e76\u652f\u6301\u591a\u8868join\u67e5\u8be2\uff0c\u9700\u8981\u591a\u8868\u67e5\u8be2\u7684\u60c5\u51b5\u8bf7\u4f7f\u7528raw_sql\u51fd\u6570\uff0c\u6267\u884c\u539f\u59cbsql\u8bed\u53e5\u3002\u4ee5\u540e\u7684\u7248\u672c\u4f1a\u8865\u5145\u6b64\u529f\u80fd\u3002\n\n\n\u8d85\u7ea7\u8868\u5b9a\u4e49\uff1a\n\n.. code-block:: python\n\n    # \u8d85\u7ea7\u8868\u6a21\u578b\u7c7b\u7ee7\u627f\u81eaSuperModel\u7c7b\n    class Meters(SuperModel):\n        cur = FloatField(db_column='c1')\n        curInt = IntegerField(db_column='c2')\n        curDouble = DoubleField(db_column='c3')\n        desc = BinaryField(db_column='des')\n        class Meta:\n            database = db\n            db_table = 'meters'\n            # Meta\u7c7b\u4e2d\u5b9a\u4e49\u7684Field\uff0c\u4e3a\u8d85\u7ea7\u8868\u7684\u6807\u7b7e\n            location = BinaryField(max_length=30)\n            groupid = IntegerField(db_column='gid')\n\n\u8d85\u7ea7\u8868\u7684\u5efa\u8868\u3001\u5220\u8868\u3001\u68c0\u67e5\u8868\u662f\u5426\u5b58\u5728\uff1a\n\n.. code-block:: python\n\n    Meters.create_table(safe=True) #\u5efa\u8868 safe\uff1a\u5982\u679c\u8868\u5b58\u5728\uff0c\u5219\u8df3\u8fc7\u5efa\u8868\u6307\u4ee4\u3002\u547d\u4ee4\u8fd0\u884c\u6210\u529f\u653e\u56deTrue,\u5931\u8d25raise\u9519\u8bef\n    # db.create_table(Meters,safe=True) #\u901a\u8fc7\u6570\u636e\u5e93\u5bf9\u8c61\u5efa\u8868\uff0c\u529f\u80fd\u540c\u4e0a\n    Meters.drop_table(safe=True) #\u5220\u8868 safe\uff1a\u5982\u679c\u8868\u4e0d\u5b58\u5728\uff0c\u5219\u8df3\u8fc7\u5220\u8868\u6307\u4ee4\u3002\u547d\u4ee4\u8fd0\u884c\u6210\u529f\u653e\u56deTrue,\u5931\u8d25raise\u9519\u8bef\n    # db.drop_table(Meters,safe=True) #\u901a\u8fc7\u6570\u636e\u5e93\u5bf9\u8c61\u5220\u8868\uff0c\u529f\u80fd\u540c\u4e0a\n    Meters.supertable_exists() #\u67e5\u770b\u8868\u662f\u5426\u5b58\u5728\uff0c\u5b58\u5728\u8fd4\u56deTrue,\u4e0d\u5b58\u5728\u8fd4\u56de\uff1aFalse\n\n\u8d85\u7ea7\u8868\u52a8\u6001\u5efa\u8868\uff1a\n\n\u8d85\u7ea7\u8868\u9664\u4e86\u4f7f\u7528\u5b9a\u4e49\u6a21\u578b\u7c7b\u7684\u65b9\u5f0f\u5efa\u8868\u5916\uff0c\u4e5f\u63d0\u4f9b\u4e86\u52a8\u6001\u5b9a\u4e49\u5b57\u6bb5\u5efa\u8868\u7684\u529f\u80fd\u3002\n\n.. code-block:: python\n\n    #\u53ef\u4ee5\u4f7f\u7528SuperModel\u7c7b\u7684\u7c7b\u65b9\u6cd5dynamic_create_table\u65b9\u6cd5\u52a8\u6001\u5efa\u8868\uff0c\u7b2c\u4e00\u4e2a\u53c2\u6570\u4e3a\u8868\u540d\uff0c\u7136\u540e\u9700\u8981\u6307\u5b9a\u6570\u636e\u5e93\uff0c\u4e0e\u662f\u5426\u5b89\u5168\u5efa\u8868\n    # \u9700\u8981\u989d\u5916\u63d0\u4f9btags\u53c2\u6570\uff0c\u53c2\u6570\u503c\u4e3a\u4e00\u4e2a\u5b57\u5178(\u4f7f\u7528\u65b9\u6cd5\u5982\u4e0b\u4f8b)\uff0c\u8bbe\u7f6e\u8d85\u7ea7\u8868\u6240\u6709\u7684\u6807\u7b7e\u3002\n    # \u5173\u952e\u8bcd\u53c2\u6570\u53ef\u4ee5\u4efb\u610f\u591a\u4e2a\uff0c\u6307\u5b9a\u8868\u4e2d\u7684\u5b57\u6bb5\u3002\n    Meter_dynamic= SuperModel.dynamic_create_table('meterSD',database=db,safe=True,tags={'gid':IntegerField(db_column='tag1')},test1 = FloatField(db_column='t1'),test2 = IntegerField(db_column='t2'))\n    # \u51fd\u6570\u8fd4\u56de\u7684\u5bf9\u8c61\u4e3aSuperModel\u7c7b\u5bf9\u8c61\u3002\u4f7f\u7528\u65b9\u6cd5\u4e0e\u9759\u6001\u7ee7\u627f\u7684\u6a21\u578b\u7c7b\u76f8\u540c\u3002\n    Meter_dynamic.supertable_exists()\n    Meter_dynamic.drop_table()\n\n\u4ece\u8868\u540d\u5efa\u7acb\u5bf9\u5e94\u7684supermodel\u7c7b\uff1a\n\n\u6570\u636e\u5e93\u4e2d\u5df2\u6709\u7684\u6570\u636e\u5e93\u8d85\u7ea7\u8868\uff0c\u53ef\u4ee5\u901a\u8fc7\u5df2\u77e5\u7684\u8868\u540d\u5efa\u7acb\u5bf9\u5e94\u7684supermodel\u7c7b\u3002\n\n.. code-block:: python\n\n    sTable = SuperModel.supermodel_from_table('rule_10',db) # rule_10\u4e3a\u6570\u636e\u8868\u7684\u8868\u540d\n    res = sTable.select().one() # \u4ece\u8868\u540d\u65b0\u5efa\u7684\u7c7b\u548c\u9759\u6001\u5efa\u7acb\u7684\u7c7b\uff0c\u4f7f\u7528\u65b9\u6cd5\u5b8c\u5168\u4e00\u81f4\n\n\u4ece\u8d85\u7ea7\u8868\u5efa\u7acb\u5b50\u8868\uff1a\n\n.. code-block:: python\n\n    SonTable_d3 = Meters.create_son_table('d3',location='beijing',groupid=3) #\u751f\u6210\u5b57\u8868\u6a21\u578b\u7c7b\u7684\u540c\u65f6\uff0c\u81ea\u52a8\u5728\u6570\u636e\u5e93\u4e2d\u5efa\u8868\u3002\n\n    SonTable_d3.table_exists() # SonTable_d3\u7684\u4f7f\u7528\u65b9\u6cd5\u548c\u7ee7\u627f\u81eaModle\u7c7b\u7684\u6a21\u578b\u7c7b\u4e00\u6837\u3002\u53ef\u4ee5\u8fdb\u884c\u63d2\u5165\u4e0e\u67e5\u8be2\u64cd\u4f5c\n    # m = SonTable_d3(cur = 65.8,curInt=10,curDouble=1.1,desc='g1',ts = datetime.datetime.now())\n    # m.save()\n\n\u65b0\u589e\u6807\u7b7e\uff1a\n\n.. code-block:: python\n\n    # \u4f7f\u7528add_tags\u65b9\u6cd5\uff0c\u53ef\u4ee5\u7ed9\u8d85\u7ea7\u8868\u65b0\u5efa\u591a\u4e2a\u6807\u7b7e\u3002\u6bcf\u4e2a\u53c2\u6570\u53ef\u4ee5\u662f\u4e00\u4e2aField\u5bf9\u8c61\uff08\u5fc5\u987b\u6307\u5b9adb_column\u5c5e\u6027\uff09\n    Meters.add_tags(IntegerField(db_column='add_tag_1'),IntegerField(db_column='add_tag_4'),BinaryField(max_length=30,db_column='add_tag_5'))\n\n\u5220\u9664\u6807\u7b7e\uff1a\n\n.. code-block:: python\n\n    # \u4f7f\u7528drop_tag\u65b9\u6cd5\u53ef\u4ee5\u5220\u9664\u8d85\u7ea7\u8868\u7684\u6807\u7b7e\uff0c\u53c2\u6570\u540d\u4e3a\u6807\u7b7e\u540d\uff0c\u4e00\u6b21\u53ea\u80fd\u5220\u9664\u4e00\u4e2a\u6807\u7b7e\n    Meters.drop_tag('add_tag_2')\n\n\u4fee\u6539\u6807\u7b7e\u540d\uff1a\n\n.. code-block:: python\n\n    # \u4f7f\u7528change_tag_name\u65b9\u6cd5\u53ef\u4ee5\u4fee\u6539\u8d85\u7ea7\u8868\u7684\u6807\u7b7e\u540d\uff0c\u53c2\u6570\u540d\u4e3a\u8981\u4fee\u6539\u7684\u6807\u7b7e\u540d\uff0c\u548c\u65b0\u7684\u6807\u7b7e\u540d\u3002\uff08\u6ce8\u610f\uff1a\u6b64\u65b9\u6cd5\u53ea\u4fee\u6539\u5bf9\u5e94\u8d85\u7ea7\u8868\u7684\u6807\u7b7e\u540d\uff0c\u5e76\u4e0d\u4fee\u6539\u7c7b\u7684\u5c5e\u6027\u540d\uff09\n    Meters.change_tag_name('add_tag_1','add_tag_2')\n\n\n\u4fee\u6539\u5b50\u8868\u6807\u7b7e\u503c\uff1a\n\n.. code-block:: python\n\n    TableT = Meters.create_son_table('d3_insert',location='beijing',gid=3)\n    # \u5b50\u8868\u53ef\u4ee5\u901a\u8fc7change_tag_value\u65b9\u6cd5\u4fee\u6539\u81ea\u5df1\u7684\u6807\u7b7e\u503c\u3002\n    TableT.change_tag_value(location='tianjin',gid = 6)\n\n\n\n\u5173\u4e8edebug\u4fe1\u606f\u6253\u5370\uff1a\n\n\u5982\u9700\u67e5\u770bcrown\u8c03\u7528tdengine\u5f15\u64ce\u65f6\u6267\u884c\u7684sql\u8bed\u53e5\u548c\u8fd4\u56de\u7684\u539f\u59cb\u6570\u636e\u3002\u53ea\u9700\u8981\u914d\u7f6ecrown\u6a21\u5757\u7684logger\u8bb0\u5f55\u5668\u7684\u65e5\u5fd7\u8f93\u51fa\u7ea7\u522b\u4e3adebug\u5373\u53ef\u3002\n\n.. code-block:: python\n\n    import logging\n    from crown import logger\n\n    logger.setLevel(logging.DEBUG) #\u914d\u7f6elogger\u5bf9\u8c61\uff0c\u5373\u53ef\u8f93\u51fa\u6267\u884cdebug\u4fe1\u606f\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "crown is a simple and small ORM for Time Series Database (TSDB) tdengine(taos), making it easy to learn and intuitive to use.",
    "version": "0.3.1",
    "project_urls": {
        "Homepage": "https://github.com/machine-w/crown"
    },
    "split_keywords": [
        "orm",
        "taos",
        "tdengine",
        "tsdb",
        "time series database",
        "connector",
        "python"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "7917b34840d2ebff9d5b2d045b0fb32d83e19d62043b7607460e7df42ac0881f",
                "md5": "ec75203a623d1d08ec0947be5a2a8142",
                "sha256": "9c40dcc779cc7a97432a88fe2f9cb9f117d27f5b126c1ff5df40ca153e5528b6"
            },
            "downloads": -1,
            "filename": "crown-0.3.1.tar.gz",
            "has_sig": false,
            "md5_digest": "ec75203a623d1d08ec0947be5a2a8142",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3",
            "size": 29760,
            "upload_time": "2023-07-09T03:29:22",
            "upload_time_iso_8601": "2023-07-09T03:29:22.481423Z",
            "url": "https://files.pythonhosted.org/packages/79/17/b34840d2ebff9d5b2d045b0fb32d83e19d62043b7607460e7df42ac0881f/crown-0.3.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-07-09 03:29:22",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "machine-w",
    "github_project": "crown",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "requests",
            "specs": [
                [
                    ">=",
                    "2.23.0"
                ]
            ]
        }
    ],
    "lcname": "crown"
}
        
Elapsed time: 0.64551s