from sqlalchemy import MetaData
from sqlalchemy import Table, Column, Integer, String
from sqlalchemy import create_engine
from sqlalchemy import ForeignKey

# Model declarations
metadata_obj = MetaData()

user_table = Table(
    "user_account",
    metadata_obj,
    Column('id', Integer, primary_key=True),
    Column('name', String(30)),
    Column('fullname', String)
)

address_table = Table(
    "address",
    metadata_obj,
    Column('id', Integer, primary_key=True),
    Column('user_id', ForeignKey('user_account.id'), nullable=False),
    Column('email_address', String, nullable=False)
)

# Connection
engine = create_engine("sqlite+pysqlite:///:memory:", future=True)

# Model migration
metadata_obj.create_all(engine)



# INSERT
from sqlalchemy import insert, select

# values method
stmt = insert(user_table).values(name='spongebob', fullname="Spongebob Squarepants")
with engine.begin() as conn:
    conn.execute(stmt)


# autogenerate values
with engine.connect() as conn:
    conn.execute(
        insert(user_table),
        [
            {"name": "sandy", "fullname": "Sandy Cheeks"},
            {"name": "patrick", "fullname": "Patrick Star"}
        ]
    )
    conn.commit()


# insert..select
select_stmt = select(user_table.c.id, user_table.c.name + "@aol.com")
insert_stmt = insert(address_table).from_select(
    ["user_id", "email_address"], select_stmt
)
with engine.begin() as conn:
    res = conn.execute(insert_stmt)



# SELECT
from sqlalchemy import select

stmt = select(user_table).where(user_table.c.name == 'spongebob')  # Where accepts binary expression
print('Where clause: ', user_table.c.name == 'spongebob')
print('Type of where clause: ', type(user_table.c.name == 'spongebob'))
with engine.connect() as conn:
    for row in conn.execute(stmt):
        print(row)
