Sqlalchemy 用整数替换文本
Sqalchemy substituting text with integers
我正在使用 Sqlalchemy 设计一个数据库来记录实验室测量值。每个测试结果我都有一个table。我想将测试结果和名称标签存储在同一行中。每当我 运行 相同的测试时,名称标签可以出现多次。因此,我不想多次存储实际标签,而是想用一个整数替换每个标签。该整数将是另一个仅存储标签的 table 的键。
数据库table定义如下:
from sqlalchemy import Column, Integer, String, Float ,
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class TestResults(Base):
__tablename__ = "test_results"
id = Column(Integer, primary_key=True)
test_name = Column(Integer) # id value in TestNames table
timestamp = Column(Integer)
test_value = Column(Float)
class TestNames(Base):
"""
Lookup table for test_name column in TestResults
"""
__tablename__ = 'test_names'
id = Column(Integer, primary_key=True)
name = Column(String)
理想情况下,我希望能够通过将 test_name 作为字符串输入数据到 TestResults table 中,例如
results = TestResults()
results.test_name = 'my_test'
results.test_value = 10.1
为了做到这一点,我想我需要一个中间函数来检查我输入 results.test_name 的字符串是否已经存在于 TestNames table 中,如果存在,那么 'real' results.test_name 填充了现有名称的 ID 号。如果该名称不存在,则将其添加到 TestNames,并将新名称的 ID 填充到 results.test_name。这样做的功能是这样的:
def test_name_creator(session,name):
"""
Input
-------
session : sqlalchemy session object
name : str
New test name
Output
--------
id : int
id of test name
"""
# Check if name already exists
name_query = session.query(TestNames).filter(TestNames.name==name).all()
if name_query!=[]:
name_id = name_query[0].id
return name_id
# name does not exist, add to TestNames() table
new_test_name = TestNames()
new_test_name.name = name
session.add(new_test_name)
session.commit()
return new_test_name.id
我想不通的是如何用上面的函数截取results.test_name='my_test'的设置,从而让returned id实际填充到results.test_name。我认为这是 association_proxy + creator 函数的工作,但我见过的所有示例 return Sqlalchemy declarative_base() class 对象,而不是简单的整数。
而不是 test_name_creator
return ID,return 实例本身,像这样:
def test_name_creator(session, name):
inst = session.query(TestNames).filter(TestNames.name == name).first()
if inst is None:
# Create new TestNames() instance and add to database
inst = TestNames(name=name)
session.add(inst)
return inst
然后,设置一个关系,以便 SQLAlchemy 找出放置 ID 的位置:
class TestResults(Base):
...
test_name_id = Column(Integer, ForeignKey(TestNames.id))
test_name = relationship(TestNames)
你这样设置名称:
results = TestResults(test_name=test_name_creator(session, "my_test"), value=10.1)
如果您想保留 test_name
的使用模式作为您可以分配给但在 TestNames
中创建行的 string
,您可以使用 association proxies combined with the UniqueObject食谱。
我正在使用 Sqlalchemy 设计一个数据库来记录实验室测量值。每个测试结果我都有一个table。我想将测试结果和名称标签存储在同一行中。每当我 运行 相同的测试时,名称标签可以出现多次。因此,我不想多次存储实际标签,而是想用一个整数替换每个标签。该整数将是另一个仅存储标签的 table 的键。
数据库table定义如下:
from sqlalchemy import Column, Integer, String, Float ,
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class TestResults(Base):
__tablename__ = "test_results"
id = Column(Integer, primary_key=True)
test_name = Column(Integer) # id value in TestNames table
timestamp = Column(Integer)
test_value = Column(Float)
class TestNames(Base):
"""
Lookup table for test_name column in TestResults
"""
__tablename__ = 'test_names'
id = Column(Integer, primary_key=True)
name = Column(String)
理想情况下,我希望能够通过将 test_name 作为字符串输入数据到 TestResults table 中,例如
results = TestResults()
results.test_name = 'my_test'
results.test_value = 10.1
为了做到这一点,我想我需要一个中间函数来检查我输入 results.test_name 的字符串是否已经存在于 TestNames table 中,如果存在,那么 'real' results.test_name 填充了现有名称的 ID 号。如果该名称不存在,则将其添加到 TestNames,并将新名称的 ID 填充到 results.test_name。这样做的功能是这样的:
def test_name_creator(session,name):
"""
Input
-------
session : sqlalchemy session object
name : str
New test name
Output
--------
id : int
id of test name
"""
# Check if name already exists
name_query = session.query(TestNames).filter(TestNames.name==name).all()
if name_query!=[]:
name_id = name_query[0].id
return name_id
# name does not exist, add to TestNames() table
new_test_name = TestNames()
new_test_name.name = name
session.add(new_test_name)
session.commit()
return new_test_name.id
我想不通的是如何用上面的函数截取results.test_name='my_test'的设置,从而让returned id实际填充到results.test_name。我认为这是 association_proxy + creator 函数的工作,但我见过的所有示例 return Sqlalchemy declarative_base() class 对象,而不是简单的整数。
而不是 test_name_creator
return ID,return 实例本身,像这样:
def test_name_creator(session, name):
inst = session.query(TestNames).filter(TestNames.name == name).first()
if inst is None:
# Create new TestNames() instance and add to database
inst = TestNames(name=name)
session.add(inst)
return inst
然后,设置一个关系,以便 SQLAlchemy 找出放置 ID 的位置:
class TestResults(Base):
...
test_name_id = Column(Integer, ForeignKey(TestNames.id))
test_name = relationship(TestNames)
你这样设置名称:
results = TestResults(test_name=test_name_creator(session, "my_test"), value=10.1)
如果您想保留 test_name
的使用模式作为您可以分配给但在 TestNames
中创建行的 string
,您可以使用 association proxies combined with the UniqueObject食谱。