У меня есть две таблицы: клиенты и транзакции.Первичный ключ таблицы клиентов связывает внешний ключ таблицы транзакций customer_id.Я хотел бы вставить данные в таблицу клиентов и вставить первичный ключ клиентов таблицы в customer_id в таблице транзакций, а затем обновить информацию в таблице транзакций на основе customer_id.Я попытался с ORM, но не смог сделать это, поэтому я использовал connection.execute()
для непосредственного запуска SQL-запроса.Тем не менее, он возвращает None, когда я использую CustomerId = engine.execute(customer_id_query).first()
.
Вот коды для двух таблиц в базе данных с именем fruited:
# -*- coding:utf-8 -*-
from sqlalchemy import Table, MetaData, Column, Integer, String, DATE, DECIMAL, ForeignKey, DateTime
from sqlalchemy.orm import mapper
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
#metadata = MetaData()
Base = declarative_base()
# customers = Table('customers', metadata,
# Column('id', Integer, primary_key=True, autoincrement=True),
# Column('name', String(20)),
# Column('phone', String(20)),
# Column('address', String(45)),
# Column('source_from', String(45))
# )
class Customers(Base):
# def __init__(self, id, name, phone, address, source_from):
# self.id = id
# self.name = name
# self.phone = phone
# self.address = address
# self.source_from = source_from
#
__tablename__ = 'customers'
id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
name = Column(String(20))
phone = Column(String(20))
address = Column(String(45))
occupation = Column(String(45))
gender = Column(String(45))
trade_freq = Column(Integer)
prefer_product = Column(String(45))
def __repr__(self):
return "<Customer(name='%s', phone='%s', address='%s', " \
"occupation='%s', gender='%s', trade_freq='%s', prefer_product='%s')" % (self.name, self.phone, self.address,
self.occupation, self.gender, self.trade_freq, self.prefer_product)
# mapper(Customers, customers)
# the table metadata is created separately with the Table construct,
# then associated with the User class via the mapper() function
# transaction = Table('transaction', metadata,
# Column('id', Integer, primary_key=True, autoincrement=True),
# Column('name', String(20)),
# Column('date', DateTime),
# Column('product', String(20)),
# Column('quantity', Integer),
# Column('amount', DECIMAL(2))
# )
class Transaction(Base):
# def __init__(self, id, name, date, product, quantity, amount):
# self.id = id
# self.name = name
# self.date = date
# self.product = product
# self.quantity = quantity
# self.amount = amount
#
__tablename__ = 'transaction'
id = Column(Integer, primary_key=True, autoincrement=True, nullable=False)
name = Column(String(20))
date = Column(DATE)
product = Column(String(20))
quantity = Column(Integer)
amount = Column(Integer)
customer_id = Column(Integer, ForeignKey('customers.id'))
comment = Column(String(100))
customer = relationship('Customers')
def __repr__(self):
return "<Transaction(name='%s', date='%s', product='%s'," \
"quantity='%s', amount='%s', customer_id='%s', comment='%s')>" % (self.name, self.date,
self.product, self.quantity,
self.amount, self.customer_id,
self.comment)
# mapper(Transaction, transaction)
Вот подробности тестового кодирования для:
def test_db_writing(file_name):
cus_columns = ['name', 'address', 'phone']
tran_columns = ['name', 'date', 'product', 'quantity', 'amount', 'comment']
index = []
cus_df = pd.DataFrame(index=index, columns=cus_columns)
engine = create_engine(conn)
book = xlrd.open_workbook(file_name)
tran = book.sheet_by_name("excelReport")
connection = engine.connect()
for r in range(1, tran.nrows):
phone = tran.cell(r, 24).value
# customer_details = engine.execute('select * from customers where phone={0}'.format(phone))
# test and found could not use pandas... too powerful...
# query = 'select * from customers where phone={0}'.format(phone)
# customer_details = get_data_from_db(query, conn, params=None)
# customer_details = session.query(Customers).filter(Customers.phone == phone).first()
customer_id_query = 'select id from fruitdb.customers where phone = {}'.format(phone)
product_list = tran.cell(r, 10).value
quantity_list = tran.cell(r, 14).value
unit_price_list = tran.cell(r, 15).value
# the cells have more than one value.
if ";" in product_list:
product_l = product_list.split(';')
quantity_l = quantity_list.split(';')
unit_price_l = unit_price_list.split(';')
for i in range(len(product_l)):
with connection.begin() as trans:
# write the related columns to db by loop
CustomerId = engine.execute(customer_id_query).first()
date = tran.cell(r, 6).value[:10]
name = tran.cell(r, 23).value
product = product_l[i]
quantity = quantity_l[i]
unit_price = unit_price_l[i]
comment = tran.cell(r, 40).value
# update the row where
# transaction_obj = Transaction(name=name, date=date, product=product,
# quantity=quantity, amount=unit_price, comment=comment)
# session.update(transaction_obj)
# transaction = session.query(Transaction).filter(Transaction.customer_id == customer_id).first()
# transaction.date = date
# transaction.name = name
# transaction.product = product
# transaction.quantity = quantity
# transaction.amount = unit_price
# transaction.comment = comment
# session.add(transaction)
# session.commit()
print(CustomerId)
transaction_updatequery = '''update fruitdb.transaction set date = {},
name = '{}', product = '{}', quantity = {}, amount = {},
comment = '{}' where customer_id = {}'''.format(date, name, product, quantity,
unit_price, comment,
CustomerId)
connection.execute(transaction_updatequery)
df = pd.DataFrame([[date, name, product, quantity, unit_price, comment]], columns=tran_columns)
df2 = cus_df.append(df)
else:
# write the columns
with connection.begin() as trans:
# write the related columns to db by loop
CustomerId = engine.execute(customer_id_query).first()
date = tran.cell(r, 6).value[:10]
name = tran.cell(r, 23).value
product = product_list
quantity = quantity_list
unit_price = unit_price_list
comment = tran.cell(r, 40).value
# transaction = session.query(Transaction).filter(Transaction.customer_id == customer_id).first()
print(CustomerId)
transaction_updatequery = '''update fruitdb.transaction set date = {},
name = '{}', product = '{}', quantity = {}, amount = {},
comment = '{}' where customer_id = {}'''.format(date, name, product, quantity,
unit_price, comment, CustomerId)
connection.execute(transaction_updatequery)
# session.add(transaction)
# session.commit()
df = pd.DataFrame([[date, name, product, quantity, unit_price, comment]], columns=tran_columns)
df2 = cus_df.append(df)
return df2
if __name__ == '__main__':
test_db_writing("se1-bj-wdp-1536140797852-602557_1.xls")
Пожалуйста, сообщите, если этоправильный способ обновить информацию в таблице транзакций, используя customer_id.Thx.