Python SQLAlchemy创建了dymanic未知表

时间:2015-07-16 09:33:56

标签: python database sqlalchemy

我有一个关于使用SQLAlchemy动态创建表的问题。我不知道python服务器脚本启动时的表名。

这是如何工作的,我编写了一个收集数据的客户端应用程序,然后使用REST(服务器)和请求(客户端)将数据推送到服务器组件。我在服务器API点捕获数据并成功将它们(params)写入数据库,这一切都很好。

当我在新位置有客户时,我的问题就出现了。服务器应在数据库(服务器)中为客户端报告到服务器的每个位置创建一个新表。

客户端自动创建一个新表,其名称基于指定的位置。但是,客户端将始终只对一个表进行工作/读/写,直到停止为止。

客户端数据库:

Database>
   Location1>
      device(String(17))
      location(Text)
      data1(Text)
      data2(Text)

在服务器上我想在同一个数据库中为客户端报告的新未知位置动态创建一个新表。因此,在服务器上,我将每个“位置”有一个表,并且数据库充满了位置。

服务器

database = "mysql://user:pwwd@localhost/SERVER"
metadata = MetaData()
engine = create_engine(database)
Base = declarative_base()

class Records(Base):
    __tablename__ = 'records'
    device = Column(String(17), primary_key=True)
    data1 = Column(Text())
    location = Column(Text())
    data2 = Column(Text())

Base.metadata.create_all(bind=engine, checkfirst=True)

我想要创建的服务器结构如下:

 Database>
       Location1>
          device(String(17))
          location(Text)
          data1(Text)
          data2(Text)
       Location2>
          device(String(17))
          location(Text)
          data1(Text)
          data2(Text)
       Location3>
          device(String(17))
          location(Text)
          data1(Text)
          data2(Text)

*问题:我发现了大量有关此主题的帖子Good Post Here,但在这篇文章中,我很难理解如何为该表创建列。然后,当'unknown_table1'在'unknown_table1'之后动态创建时,我将如何在类外(ORM)调用'unknown_table1'。

我发现该表是否已存在:

from sqlalchemy.engine.reflection import Inspector
inspector = Inspector.from_engine(engine)
    def known_location(self, _loc):
        global inspector
        global dyntable
        _know_tables = inspector.get_table_names()
        if _loc not in _know_tables:
            create the table and add the data to it on your own!.

非常感谢任何协助。

1 个答案:

答案 0 :(得分:0)

我找到了解决方案。请告诉我如何改进它。

我设置了一个标准的数据库连接,然后连接到服务器表,如果它不存在则创建它。

_location = "SERVER"

Records = Table(_location, metadata,
    Column('device', String(17), primary_key=True),
    Column('data1', Text()),
    Column('location', Text()),
    Column('data2', Text()),
    extend_existing=True
)
Base.metadata.create_all(bind=engine, checkfirst=True)

然后我有一个序列,通过该序列使用REST将数据发布到服务器。然后我将参数解析为变量,然后传递给下面的def。

def collector(_device, _data1, _data2, _loc):
    global session
    global metadata
    Records = Table(_loc, metadata,
        Column('device', String(17), primary_key=True),
        Column('data1', Text()),
        Column('location', Text()),
        Column('data2', Text()),
        extend_existing=True
    )
    check = exists().where(Records.c.device==_device)
    if check == True:
        updt = update(Records).where(Records.c.device==_device).values(data1=_data1, location=_loc, data2=_data2)
        session.add(updt)
        session.commit()
    else:
        Create_new_Table(_loc)
        ins = Records.insert().values(debice=_device, data1=_data1, location=_loc, data2=_data2)
        session.execute(ins)
    session.commit()
    session.close()

如果表不存在,那么我调用一个名为" Create_new_Table()" ...的函数。

def Create_new_Table(_loc):
    global engine
    global metadata
    global Base
    Records = Table(_loc, metadata,
        Column('device', String(17), primary_key=True),
        Column('data1', Text()),
        Column('location', Text()),
        Column('data2', Text()),
        extend_existing=True
    )
    Base.metadata.create_all(bind=engine, checkfirst=True)
    Records.create(engine, checkfirst=True)

如果您认为我可以改进任何事情,请告诉我。