On 05/15/2017 06:43 AM, mdob wrote:
Just curious. Let's say we have a complex primary key of user_id (integer), project_id (integer) and date (timestamp). After adding and committing we don't have the PK and we won't be able to update it. Is that right?

if you were using Postgresql this would be no problem, because we use RETURNING in the INSERT to get all the server default values back directly. But MySQL does not support this, for primary key values that are server-generated, we can only get the AUTO_INCREMENT integer back, that's correct. We don't call last_inserted_id() directly, this is a function of the driver which gives us the number via cursor.lastrowid.

For things like dates, for us to know the PK of the row we just inserted, we need to generate it before we do the insert. So in your Table def you need to use client side "default=func.utcnow()" or whatever so that SQLAlchemy Core knows it can run that default generation function as a separate SQL SELECT; this does not preclude being able to have a server default on the column as well, it just would not be used in the case of ORM insert.



If it was auto-increment integer then it would probably be fine. PK would be fetched using last_inster_id() in mysql or similar method in other dialects.

|
from sqlalchemy import create_engine, Column, Integer, TIMESTAMP, FetchedValue
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

Base = declarative_base()

engine = create_engine('mysql+mysqldb://root:****@192.168.1.12:3306/test?charset=utf8', echo=True)

class Timesheet(Base):
     __tablename__ = 'timesheet'
     user_id = Column(Integer, primary_key=True)
     project_id = Column(Integer, primary_key=True)
date = Column(TIMESTAMP(), primary_key=True, nullable=False, server_default=FetchedValue())


session = sessionmaker(engine)()
t1 = Timesheet(user_id=1, project_id=1)
session.add(t1)
session.commit()

print t1.date
|


|
2017-05-15 11:46:09,411 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'sql_mode'
2017-05-15 11:46:09,411 INFO sqlalchemy.engine.base.Engine ()
2017-05-15 11:46:09,412 INFO sqlalchemy.engine.base.Engine SELECT DATABASE()
2017-05-15 11:46:09,412 INFO sqlalchemy.engine.base.Engine ()
2017-05-15 11:46:09,412 INFO sqlalchemy.engine.base.Engine show collation where `Charset` = 'utf8' and `Collation` = 'utf8_bin'
2017-05-15 11:46:09,413 INFO sqlalchemy.engine.base.Engine ()
2017-05-15 11:46:09,413 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS CHAR(60)) AS anon_1
2017-05-15 11:46:09,413 INFO sqlalchemy.engine.base.Engine ()
2017-05-15 11:46:09,414 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS CHAR(60)) AS anon_1
2017-05-15 11:46:09,414 INFO sqlalchemy.engine.base.Engine ()
2017-05-15 11:46:09,414 INFO sqlalchemy.engine.base.Engine SELECT CAST('test collated returns' AS CHAR CHARACTER SET utf8) COLLATE utf8_bin AS anon_1
2017-05-15 11:46:09,414 INFO sqlalchemy.engine.base.Engine ()
2017-05-15 11:46:09,415 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2017-05-15 11:46:09,416 INFO sqlalchemy.engine.base.Engine INSERT INTO timesheet (user_id, project_id) VALUES (%s, %s)
2017-05-15 11:46:09,416 INFO sqlalchemy.engine.base.Engine (1, 1)
2017-05-15 11:46:09,416 INFO sqlalchemy.engine.base.Engine COMMIT
Traceback (most recent call last):
   File "/home/mike/projects/sandbox/box7.py", line 21, in <module>
     print t1.date
File "/home/mike/envs/slashdb9/local/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 237, in __get__
     return self.impl.get(instance_state(instance), dict_)
File "/home/mike/envs/slashdb9/local/lib/python2.7/site-packages/sqlalchemy/orm/attributes.py", line 578, in get
     value = state._load_expired(state, passive)
File "/home/mike/envs/slashdb9/local/lib/python2.7/site-packages/sqlalchemy/orm/state.py", line 474, in _load_expired
     self.manager.deferred_scalar_loader(self, toload)
File "/home/mike/envs/slashdb9/local/lib/python2.7/site-packages/sqlalchemy/orm/loading.py", line 669, in load_scalar_attributes
     raise orm_exc.ObjectDeletedError(state)
sqlalchemy.orm.exc.ObjectDeletedError: Instance '<Timesheet at 0x7f9ad5931d50>' has been deleted, or its row is otherwise not present.
2017-05-15 11:46:09,419 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2017-05-15 11:46:09,420 INFO sqlalchemy.engine.base.Engine SELECT timesheet.user_id AS timesheet_user_id, timesheet.project_id AS timesheet_project_id, timesheet.date AS timesheet_date
FROM timesheet
WHERE timesheet.user_id = %s AND timesheet.project_id = %s AND timesheet.date IS NULL
2017-05-15 11:46:09,420 INFO sqlalchemy.engine.base.Engine (1, 1)
|


--
SQLAlchemy -
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable Example. See http://stackoverflow.com/help/mcve for a full description.
---
You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected] <mailto:[email protected]>. To post to this group, send email to [email protected] <mailto:[email protected]>.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

--
SQLAlchemy - The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- You received this message because you are subscribed to the Google Groups "sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to