-
Notifications
You must be signed in to change notification settings - Fork 400
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for non auto-increment/integer primary keys #92
Comments
Yes, there have been a few bug reports around this bad feature. |
Thanks for getting back to me. I planned on having a stab at it, but as you said its not the most straight forward thing in the world hey! Could it be a simple as providing a separate base for this use case?? I suppose the functionality is spread across two classes though. Perhaps even just a flag to disable the sequence generation functionality in base.py (forgive me if i got that file wrong) that might be nice and explicit and could just leave the user responsible for handling primary keys in any use case? |
All happens in The main issue on both sides is that, actually, pks may be non numeric. I guess the simplest way to handle the problem would be to look at introspections tools in the frameworks to detect whether the table's primary key is an AUTO_INCREMENT-like field. Another option is to simply try to fetch the latest If SQLAlchemy introspections features make it easy to find the type of the primary key column, this check should be performed before attempting to call |
Hey Guys Currently battling with this now on the SQLAlchemy side of things, had a bit of a hack and basically did this: from sqlalchemy.types import Integer
@classmethod
def _setup_next_sequence(cls, *args, **kwargs):
"""Compute the next available PK, based on the 'pk' database field."""
session = cls.FACTORY_SESSION
model = cls.FACTORY_FOR
pk = getattr(model, model.__mapper__.primary_key[0].name)
# Check if the primary key type is an Integer, if it is then we do the normal max
# stuff else return 1 - we might also need to check BigInteger as well
if isinstance(pk.type, Integer):
max_pk = session.query(max(pk)).one()[0]
if isinstance(max_pk, int):
return max_pk + 1 if max_pk else 1
return 1 Seems to do the job. |
It's even easier. Just supply __sequence to the factory. It's not heavily documented, though. |
Does this not defeat the purpose of the I think what @krak3n suggested is fine. If you use a |
@NiklasMM Well, it should "just work" anyway. The only purpose of this weird magic with automagical sequence initialization is to support the following scenario:
Without this hack, the Sequence counter will be set to 1 at the beginning of each script run, so both runs would generate objects with the same values for the unique field ; thus conflicting and crashing. I'm willing to remove this hack : the above scenario isn't a standard use of the library, and the behavior can be easily achieved with custom |
+1 |
Related to issues #78, #92, #103, #111, #153, #170 The default value of all sequences is now 0; the automagic ``_setup_next_sequence`` behavior of Django/SQLAlchemy has been removed. This feature's only goal was to allow the following scenario: 1. Run a Python script that uses MyFactory.create() a couple of times (with a unique field based on the sequence counter) 2. Run the same Python script a second time Without the magical ``_setup_next_sequence``, the Sequence counter would be set to 0 at the beginning of each script run, so both runs would generate objects with the same values for the unique field ; thus conflicting and crashing. The above behavior having only a very limited use and bringing various issues (hitting the database on ``build()``, problems with non-integer or composite primary key columns, ...), it has been removed. It could still be emulated through custom ``_setup_next_sequence`` methods, or by calling ``MyFactory.reset_sequence()``.
This issue has been fixed in 13d310f, and will be part of the 2.5.0 release. |
Our system makes use of UUID column type in postgres in some places. At the moment FactoryBoy will try to perform a lookup on the primary key to determine the next sequence using the max() function on the primary key column of a model
This is obviously not going to work when we have UUID's
Is this something you might consider allowing for?
The text was updated successfully, but these errors were encountered: