Re: How to handle `default` column values before/after commit()

2019-05-06 Thread Mike Bayer
On Mon, May 6, 2019 at 12:06 AM  wrote:
>
> Suppose the following code:
>
> # We define a base for all DB objects, currently empty.
> class _Base:
> pass
>
> Base = declarative_base(cls=_Base, metadata=MetaData(naming_convention=…))
>
> # Then the objects.
> class User(Base):
> __tablename__ = "users"
>
> id = Column(UUID(), default=uuid.uuid4, primary_key=True)
> …
>
> For the majority of code this works well and the id is initialized whenever 
> the object is committed. However, there are cases when I need to get a hold 
> of a new object’s id and that happens before the commit. In such cases the id 
> is not set yet, and I have extra code which sets the id manually.
>
> That feels crummy to me.
>
> Now I wonder if that’s poor implementation because a new object should always 
> be committed before use, or if I should perhaps expand the _Base class, for 
> example:
>
> class _Base:
>
> def __init__(self, *args, **kwargs):
> super().__init__(args, kwargs)
> if hasargs(self, "id"):
> self.id = uuid.uuid4()
>
> That way, every object would have an id assigned and if the object is loaded 
> from the db then that initial id would be overwritten. Not pretty either, but 
> maybe less crummy than the current implementation.
>
> What are your thoughts?

yes but here is the most canonical approach:

import uuid

from sqlalchemy import Column
from sqlalchemy import event
from sqlalchemy.dialects.postgresql import UUID
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()


class HasUUID(object):
  id = Column(UUID(), default=uuid.uuid4, primary_key=True)

@event.listens_for(HasUUID, "init", propagate=True)
def init(obj, arg, kw):
obj.id = uuid.uuid4()

class User(HasUUID, Base):
__tablename__ = 'user'


u1 = User()

print(u1.id)



Alternatively, you can write an event that scans for columns that
contain a Python level default and invokes them.  I think I did this
for someone once but it's apparently not in the wiki, but in any case
doing this using class-level inheritance is IMO the cleanest way since
your User class takes on the role of HasUUID explicitly.






>
> Much thanks!
> Jens
>
> --
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy-alembic" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sqlalchemy-alembic+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy-alembic" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy-alembic+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: How to handle `default` column values before/after commit()

2019-05-06 Thread jens . troeger
Sorry, I meant flush 

 
in the above post and not commit!

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy-alembic" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy-alembic+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


How to handle `default` column values before/after commit()

2019-05-05 Thread jens . troeger
Suppose the following code:

# We define a base for all DB objects, currently empty.
class _Base:
pass

Base = declarative_base(cls=_Base, metadata=MetaData(naming_convention=…))

# Then the objects.
class User(Base):
__tablename__ = "users"

id = Column(UUID(), default=uuid.uuid4, primary_key=True)
…

For the majority of code this works well and the id is initialized whenever 
the object is committed. However, there are cases when I need to get a hold 
of a new object’s id and that happens before the commit. In such cases the 
id is not set yet, and I have extra code which sets the id manually.

That feels crummy to me.

Now I wonder if that’s poor implementation because a new object should 
always be committed before use, or if I should perhaps expand the _Base 
class, for example:

class _Base:

def __init__(self, *args, **kwargs):
super().__init__(args, kwargs)
if hasargs(self, "id"):
self.id = uuid.uuid4()

That way, every object would have an id assigned and if the object is 
loaded from the db then that initial id would be overwritten. Not pretty 
either, but maybe less crummy than the current implementation.

What are your thoughts?

Much thanks!
Jens

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy-alembic" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy-alembic+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.