从 sqlalchemy orm 中的 2 个 csv 文件定义函数
define function from 2 csv files in sqlalchemy orm
我有 2 个 csv 文件。
一个文件(id.csv)包含2列,ID和Names。
另一个csv(relations.csv)也包含2列,TeacherID和StudentID。此文件用于根据学生的 ID 显示特定教师正在教多少学生。
第一个 csv 文件:
ID Name
ID01 John
ID02 Jane
ID03 Tom
ID04 Bill
ID05 Steve
ID06 Sarah
第二个 csv 文件:
TeacherID StudentID
ID01 ID03
ID01 ID04
ID02 ID06
ID01 ID05
我已经写了 2 类,ID 和关系,定义表名、列(字符串)、关系和外键。
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Enum, Float, ForeignKey
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm import relationship
Base = declarative_base()
class ID(Base):
__tablename__ = "id"
index = Column(String, primary_key=True)
name = Column(String)
def __repr__(self):
return "%s %s" %(self.index, self.name)
class Relations(Base):
__tablename__ = 'relations'
aindex = Column('ID', Integer, primary_key=True)
frompax = Column(String, ForeignKey("id.index"))
topax = Column(String, ForeignKey('id.index'))
rsfrom = relationship("ID", foreign_keys="Relations.frompax")
rsto = relationship("ID", foreign_keys="Relations.topax")
def __repr__(self):
return "%s %s" %(self.frompax, self.topax)
#Create database engine
engine = create_engine('sqlite:///test', echo=True)
engine
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
#Read the CSV files
import csv
with open('id.csv') as f:
reader = csv.reader(f)
header = next(reader)
for row in reader:
person = ID(
index=row[0],
name=row[1]
)
session.add(person)
session.commit()
with open('relations.csv') as f:
reader = csv.reader(f)
header = next(reader)
for row in reader:
rel = Acquaintance(
frompax=row[0],
topax=row[1],
)
session.add(rel)
session.commit()
我想写一个函数,当我输入老师的 ID 时,它会 return he/she 教过的所有学生的名字。到目前为止,我已经设法编写了功能代码,并且 return 学生根据他们的 ID。
def direct(id):
return list(session.query(Relations).filter_by(frompax=id))
direct('ID01')
[ID01 ID03,
ID01 ID04,
ID01 ID05]
我怎样才能 return 只显示学生姓名?
示例:
direct('ID01')
[Tom,
Bill,
Steve]
import csv
def direct(id):
id_list = list(session.query(Relations).filter_by(frompax=id))
name_list = []
with open("your_first_file.csv", "r") as f:
reader = csv.reader(f, delimiter='\t')
for i, line in enumerate(reader):
if line[0] in id_list:
name_list.append(line[1])
return name_list
看起来您正在尝试创建 self-referential many to many relationship。这需要对您的代码进行一些更改以使其与文档中的代码相匹配。
首先,将Relations
转换成Table with two columns (note that it uses the same metadata作为模型):
Base = declarative_base()
relations_table = Table(
'relations',
Base.metadata,
Column('frompax', String, ForeignKey('id.index')),
Column('topax', String, ForeignKey('id.index')),
)
将关系移动到ID
;它们可以表示为单一关系。
class ID(Base):
__tablename__ = 'id'
index = Column(String, primary_key=True)
name = Column(String)
# ID's that have this row as relation.
has_relations = relationship(
'ID',
secondary=relations_table,
primaryjoin=index == relations_table.c.topax,
secondaryjoin=index == relations_table.c.frompax,
backref='is_related_to',
)
def __repr__(self):
return '%s %s' % (self.index, self.name)
最后,更改direct
函数,使用Session.get, and then use a list comprehension通过主键获取ID
,收集相关对象的名称。
def direct(id_):
instance = session.get(ID, id_)
return [r.name for r in instance.is_related_to]
我有 2 个 csv 文件。
一个文件(id.csv)包含2列,ID和Names。
另一个csv(relations.csv)也包含2列,TeacherID和StudentID。此文件用于根据学生的 ID 显示特定教师正在教多少学生。
第一个 csv 文件:
ID Name
ID01 John
ID02 Jane
ID03 Tom
ID04 Bill
ID05 Steve
ID06 Sarah
第二个 csv 文件:
TeacherID StudentID
ID01 ID03
ID01 ID04
ID02 ID06
ID01 ID05
我已经写了 2 类,ID 和关系,定义表名、列(字符串)、关系和外键。
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, Enum, Float, ForeignKey
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.orm import relationship
Base = declarative_base()
class ID(Base):
__tablename__ = "id"
index = Column(String, primary_key=True)
name = Column(String)
def __repr__(self):
return "%s %s" %(self.index, self.name)
class Relations(Base):
__tablename__ = 'relations'
aindex = Column('ID', Integer, primary_key=True)
frompax = Column(String, ForeignKey("id.index"))
topax = Column(String, ForeignKey('id.index'))
rsfrom = relationship("ID", foreign_keys="Relations.frompax")
rsto = relationship("ID", foreign_keys="Relations.topax")
def __repr__(self):
return "%s %s" %(self.frompax, self.topax)
#Create database engine
engine = create_engine('sqlite:///test', echo=True)
engine
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
#Read the CSV files
import csv
with open('id.csv') as f:
reader = csv.reader(f)
header = next(reader)
for row in reader:
person = ID(
index=row[0],
name=row[1]
)
session.add(person)
session.commit()
with open('relations.csv') as f:
reader = csv.reader(f)
header = next(reader)
for row in reader:
rel = Acquaintance(
frompax=row[0],
topax=row[1],
)
session.add(rel)
session.commit()
我想写一个函数,当我输入老师的 ID 时,它会 return he/she 教过的所有学生的名字。到目前为止,我已经设法编写了功能代码,并且 return 学生根据他们的 ID。
def direct(id):
return list(session.query(Relations).filter_by(frompax=id))
direct('ID01')
[ID01 ID03,
ID01 ID04,
ID01 ID05]
我怎样才能 return 只显示学生姓名? 示例:
direct('ID01')
[Tom,
Bill,
Steve]
import csv
def direct(id):
id_list = list(session.query(Relations).filter_by(frompax=id))
name_list = []
with open("your_first_file.csv", "r") as f:
reader = csv.reader(f, delimiter='\t')
for i, line in enumerate(reader):
if line[0] in id_list:
name_list.append(line[1])
return name_list
看起来您正在尝试创建 self-referential many to many relationship。这需要对您的代码进行一些更改以使其与文档中的代码相匹配。
首先,将Relations
转换成Table with two columns (note that it uses the same metadata作为模型):
Base = declarative_base()
relations_table = Table(
'relations',
Base.metadata,
Column('frompax', String, ForeignKey('id.index')),
Column('topax', String, ForeignKey('id.index')),
)
将关系移动到ID
;它们可以表示为单一关系。
class ID(Base):
__tablename__ = 'id'
index = Column(String, primary_key=True)
name = Column(String)
# ID's that have this row as relation.
has_relations = relationship(
'ID',
secondary=relations_table,
primaryjoin=index == relations_table.c.topax,
secondaryjoin=index == relations_table.c.frompax,
backref='is_related_to',
)
def __repr__(self):
return '%s %s' % (self.index, self.name)
最后,更改direct
函数,使用Session.get, and then use a list comprehension通过主键获取ID
,收集相关对象的名称。
def direct(id_):
instance = session.get(ID, id_)
return [r.name for r in instance.is_related_to]