based on my model:
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
Base = declarative_base()
class Session(Base):
__tablename__ = 'sessions'
id = Column(Integer, primary_key=True)
token = Column(String(200))
user_id = Column(Integer, ForeignKey('app_users.id'))
user = relationship('model.user.User', back_populates='sessions')
I want to instantiate a new session through:
session = Session(token='test-token-123')
But i get:
AttributeError: mapper
The full stacktrace:
Traceback (most recent call last):
File "/home/ubuntu/.local/lib/python3.5/site-packages/falcon/api.py", line 227, in __call__
responder(req, resp, **params)
File "./app_user/register.py", line 13, in on_post
session = Session(token='test-token-123')
File "<string>", line 2, in __init__
File "/home/ubuntu/.local/lib/python3.5/site-packages/sqlalchemy/orm/instrumentation.py", line 347, in _new_state_if_none
state = self._state_constructor(instance, self)
File "/home/ubuntu/.local/lib/python3.5/site-packages/sqlalchemy/util/langhelpers.py", line 764, in __get__
obj.__dict__[self.__name__] = result = self.fget(obj)
File "/home/ubuntu/.local/lib/python3.5/site-packages/sqlalchemy/orm/instrumentation.py", line 177, in _state_constructor
self.dispatch.first_init(self, self.class_)
File "/home/ubuntu/.local/lib/python3.5/site-packages/sqlalchemy/event/attr.py", line 256, in __call__
fn(*args, **kw)
File "/home/ubuntu/.local/lib/python3.5/site-packages/sqlalchemy/orm/mapper.py", line 2976, in _event_on_first_init
configure_mappers()
File "/home/ubuntu/.local/lib/python3.5/site-packages/sqlalchemy/orm/mapper.py", line 2872, in configure_mappers
mapper._post_configure_properties()
File "/home/ubuntu/.local/lib/python3.5/site-packages/sqlalchemy/orm/mapper.py", line 1765, in _post_configure_properties
prop.init()
File "/home/ubuntu/.local/lib/python3.5/site-packages/sqlalchemy/orm/interfaces.py", line 184, in init
self.do_init()
File "/home/ubuntu/.local/lib/python3.5/site-packages/sqlalchemy/orm/relationships.py", line 1653, in do_init
self._process_dependent_arguments()
File "/home/ubuntu/.local/lib/python3.5/site-packages/sqlalchemy/orm/relationships.py", line 1710, in _process_dependent_arguments
self.target = self.mapper.mapped_table
File "/home/ubuntu/.local/lib/python3.5/site-packages/sqlalchemy/util/langhelpers.py", line 850, in __getattr__
return self._fallback_getattr(key)
File "/home/ubuntu/.local/lib/python3.5/site-packages/sqlalchemy/util/langhelpers.py", line 828, in _fallback_getattr
raise AttributeError(key)
I have no idea where this error is coming from and i can not really debug it.. anybody could help me with this issue?
Thanks and Greetings!
Looking at the traceback you can see these lines:
...
File "/home/ubuntu/.local/lib/python3.5/site-packages/sqlalchemy/orm/relationships.py", line 1653, in do_init
self._process_dependent_arguments()
File "/home/ubuntu/.local/lib/python3.5/site-packages/sqlalchemy/orm/relationships.py", line 1710, in _process_dependent_arguments
self.target = self.mapper.mapped_table
...
which narrow your problem down quite a bit. The relationship
user = relationship('model.user.User', back_populates='sessions')
uses a Python evaluable string as the argument, the use of which is further explained in "Configuring Relationships":
Relationships to other classes are done in the usual way, with the added feature that the class specified to relationship() may be a string name. The “class registry” associated with Base is used at mapper compilation time to resolve the name into the actual class object, which is expected to have been defined once the mapper configuration is used
If you've not imported models.user module anywhere before you try to instantiate a Session object for the first time, then the name resolving fails because the class User has not been created yet and does not exist in the registry. In other words for the name resolving to work, all classes must have been defined, which means that their bodies must have been executed.
And if you actually have imported the models.user module, check your other models and that their related model classes have been defined. Using your models for the first time triggers mapper compilation/configuration, so the source of the error could be other models as well.
Related
I'm trying to create an Order model using SQLAlchemy with a Column having an Array of ProductItem Class defined, but it is throwing an exception
Both the classes are defined in the same file
models.py
# Product Item Class
class ProductItem(Base):
__tablename__ = 'product_items'
id = Column(Integer, primary_key=True, index=True)
productName = Column(String,index=True,nullable=False)
productBrand = Column(String, nullable=False)
def __repr__(self):
return "<ProductList(productName = '%s', productCategoryName = '%s')>" % (
self.productName,
self.productCategoryName
)
#Order Class
class Order(Base):
__tablename__ = 'orders'
id= Column(Integer, index=True, primary_key=True)
dateCreated = Column(DateTime,nullable=False)
dateDelivered = Column(DateTime, nullable=True)
orderItem = Column(ARRAY(ProductItem), nullable=False) # This Column
orderStatus = Column(String, nullable=False)
Exception:
>alembic revision --autogenerate -m "Initial db with order"
INFO [alembic.runtime.migration] Context impl PostgresqlImpl.
INFO [alembic.runtime.migration] Will assume transactional DDL.
INFO [alembic.autogenerate.compare] Detected added table 'orders'
INFO [alembic.autogenerate.compare] Detected added index 'ix_orders_businessId' on '['businessId']'
INFO [alembic.autogenerate.compare] Detected added index 'ix_orders_customerId' on '['customerId']'
INFO [alembic.autogenerate.compare] Detected added index 'ix_orders_id' on '['id']'
INFO [alembic.ddl.postgresql] Detected sequence named 'product_categories_id_seq' as owned by integer column 'product_categories(id)', assuming SERIAL and omitting
INFO [alembic.ddl.postgresql] Detected sequence named 'business_billing_id_seq' as owned by integer column 'business_billing(id)', assuming SERIAL and omitting
INFO [alembic.ddl.postgresql] Detected sequence named 'business_timings_id_seq' as owned by integer column 'business_timings(id)', assuming SERIAL and omitting
INFO [alembic.ddl.postgresql] Detected sequence named 'product_items_id_seq' as owned by integer column 'product_items(id)', assuming SERIAL and omitting
INFO [alembic.ddl.postgresql] Detected sequence named 'inventory_id_seq' as owned by integer column 'inventory(id)', assuming SERIAL and omitting
Generating D:\app Backend\db-migration\versions\ceff7117b4cb_initial_db_without_order.py ... done
Traceback (most recent call last):
File "c:\users\mahesh\appdata\local\programs\python\python39\lib\runpy.py", line 197, in _run_module_as_main
return _run_code(code, main_globals, None,
File "c:\users\mahesh\appdata\local\programs\python\python39\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "D:\app Backend\env\Scripts\alembic.exe\__main__.py", line 7, in <module>
File "d:\app backend\env\lib\site-packages\alembic\config.py", line 559, in main
CommandLine(prog=prog).main(argv=argv)
File "d:\app backend\env\lib\site-packages\alembic\config.py", line 553, in main
self.run_cmd(cfg, options)
File "d:\app backend\env\lib\site-packages\alembic\config.py", line 530, in run_cmd
fn(
File "d:\app backend\env\lib\site-packages\alembic\command.py", line 219, in revision
scripts = [script for script in revision_context.generate_scripts()]
File "d:\app backend\env\lib\site-packages\alembic\command.py", line 219, in <listcomp>
scripts = [script for script in revision_context.generate_scripts()]
File "d:\app backend\env\lib\site-packages\alembic\autogenerate\api.py", line 533, in generate_scripts
yield self._to_script(generated_revision)
File "d:\app backend\env\lib\site-packages\alembic\autogenerate\api.py", line 449, in _to_script
return self.script_directory.generate_revision(
File "d:\app backend\env\lib\site-packages\alembic\script\base.py", line 658, in generate_revision
script = Script._from_path(self, path)
File "d:\app backend\env\lib\site-packages\alembic\script\base.py", line 851, in _from_path
return cls._from_filename(scriptdir, dir_, filename)
File "d:\app backend\env\lib\site-packages\alembic\script\base.py", line 904, in _from_filename
module = util.load_python_file(dir_, filename)
File "d:\app backend\env\lib\site-packages\alembic\util\pyfiles.py", line 97, in load_python_file
module = load_module_py(module_id, path)
File "d:\app backend\env\lib\site-packages\alembic\util\compat.py", line 182, in load_module_py
spec.loader.exec_module(module)
File "<frozen importlib._bootstrap_external>", line 786, in exec_module
File "<frozen importlib._bootstrap_external>", line 923, in get_code
File "<frozen importlib._bootstrap_external>", line 853, in source_to_code
File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
File "D:\App Backend\db-migration\versions\ceff7117b4cb_initial_db_without_order.py", line 25
sa.Column('orderItem', sa.ARRAY(app.models.<app.models.ProductItem object at 0x00000256DF9ED100>), nullable=False),
^
SyntaxError: invalid syntax
Searched a lot but couldn't find any docs describing custom types for the array. I need a way to store an array of ProductItem class in Order Class. Any help would be appreciated. Thank you!
From the PostgreSQL: documentation:
PostgreSQL allows columns of a table to be defined as variable-length multidimensional arrays. Arrays of any built-in or user-defined base type, enum type, composite type, range type, or domain can be created.
Hence, you will not be able to create an ARRAY column of just any Python class, unless you create a corresponding user-defined type in the database, which is most likely against the reason of how one should use SQLAlchemy.
What you need is a way to create a Many To Many relationship which requires an association table.
See also the answer to this question, a similar question although it focused on enforcing ForeignKey constraint from the ARRAY datatype.
I am trying to build a server to sample a streaming price feed and update a postgres DB using SQLAlchemy. I am using threaded instances of a mapped class, which seems to work but is not stable.
There are no issues with 1 or 2 instances of the Stream class, but with say 10, the thread fails randomly and silently. Each time before it fails, SQLAlchemy gives an error message, so it seems this is what is killing the thread. There is nothing wrong with the stream, it is always stable.
Have I missed something with the SQLAlchemy setup? Is there a better way of feeding multiple realtime subscriptions into SQL?
The code:
import time
import json
from threading import Thread, Lock
import sqlalchemy as db
from sqlalchemy.orm import scoped_session, sessionmaker, relationship
from sqlalchemy.ext.declarative import declarative_base
# Setup SQLAlchemy
engine = db.create_engine('postgresql://localhost:5432/Project', echo=False)
metadata = db.MetaData(bind=engine)
Session = scoped_session(sessionmaker(bind=engine))
Base = declarative_base()
Base.metadata.create_all(engine)
session = Session()
#DB classes
#static data table
class StockMaster(Base):
__tablename__ = 'stock_master'
id = db.Column(db.Integer, primary_key=True)
ticker = db.Column(db.String)
stock_name = db.Column(db.String)
#classmethod
def find_by_ticker(cls,ticker):
return session.query(StockMaster).filter(StockMaster.ticker==ticker).first()
#live data table
class StockLive(Base):
__tablename__ = 'stock_live'
id = db.Column(db.Integer, primary_key=True)
quote = db.Column(db.Numeric)
timestamp = db.Column(db.Numeric)
ticker_id = db.Column(db.Integer, db.ForeignKey('stock_master.id'))
ticker = relationship("StockMaster", foreign_keys=[ticker_id])
def __init__(self, quote, ticker_id, timestamp):
self.quote=quote
self.ticker_id=ticker_id
self.timestamp=timestamp
def save_to_db(self):
session.add(self)
session.commit()
#classmethod
def find_by_ticker_id(cls,ticker_id):
return session.query(StockLive).filter(StockLive.ticker_id==ticker_id).first()
#classmethod
def find_by_ticker(cls,ticker):
ticker_id = StockMaster.find_by_ticker(ticker).id
return session.query(StockLive).filter(StockLive.ticker_id==ticker_id).first()
class Stream(Thread):
def __init__(self,ticker):
Thread.__init__(self)
self.ticker=ticker
self.quote=1
self.data_set = StockLive.find_by_ticker(self.ticker)
self.count=0
def run(self):
con.subscribe(self.ticker)
current_mid=1
while True:
new_data = json.loads(con.get_price(self.ticker).to_json())
new_mid = new_data['Mid']
if new_mid == current_mid:
pass
else:
current_mid = new_mid
self.data_set.quote = current_mid
self.data_set.timestamp = time.time()
try:
self.data_set.save_to_db()
self.count+=1
except:
self.data_set = StockLive.find_by_ticker(self.ticker)
print('error saving to db for '+self.ticker)
time.sleep(.1)
if __name__ == '__main__':
threads={}
for ticker in tickerlist:
try:
threads[ticker]=Stream(ticker)
threads[ticker].setName('Thread ' + ticker)
threads[ticker].start()
except:
print('Error setting up '+ticker)
while True:
for ticker in tickerlist:
if threads[ticker].isAlive()==False:
threads[ticker]=Stream(ticker)
SQLAlchemy error message:
/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py:2323:
SAWarning: Usage of the 'Session.add()' operation is not currently
supported within the execution stage of the flush process. Results may
not be consistent. Consider using alternative event listeners or
connection-level operations instead. % method)
/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py:2425:
SAWarning: Attribute history events accumulated on 1 previously clean
instances within inner-flush event handlers have been reset, and will
not result in database updates. Consider using set_committed_value()
within inner-flush event handlers to avoid this warning. % len_)
Exception in thread Thread MSFT: Traceback (most recent call last):
File
"/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py",
line 2436, in _flush
transaction.commit() File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py",
line 465, in commit
self._assert_active(prepared_ok=True) File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py",
line 285, in _assert_active
raise sa_exc.ResourceClosedError(closed_msg) sqlalchemy.exc.ResourceClosedError: This transaction is closed
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File
"", line 48, in run
self.data_set.save_to_db() File "", line 44, in save_to_db
session.commit() File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py",
line 954, in commit
self.transaction.commit() File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py",
line 467, in commit
self._prepare_impl() File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py",
line 447, in _prepare_impl
self.session.flush() File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py",
line 2313, in flush
self._flush(objects) File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py",
line 2440, in _flush
transaction.rollback(_capture_exception=True) File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/util/langhelpers.py",
line 76, in exit
compat.reraise(type_, value, traceback) File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/util/compat.py",
line 249, in reraise
raise value File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py",
line 2440, in _flush
transaction.rollback(_capture_exception=True) File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py",
line 483, in rollback
self._assert_active(prepared_ok=True, rollback_ok=True) File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py",
line 285, in _assert_active
raise sa_exc.ResourceClosedError(closed_msg) sqlalchemy.exc.ResourceClosedError: This transaction is closed
During handling of the above exception, another exception occurred:
Traceback (most recent call last): File
"/anaconda3/lib/python3.7/threading.py", line 917, in _bootstrap_inner
self.run() File "", line 53, in run
self.data_set = StockLive.find_by_ticker(self.ccy) File "", line 52, in find_by_ticker
ticker_id = StockMaster.find_by_ticker(ticker).id File "", line 23, in find_by_ticker
return session.query(StockMaster).filter(StockMaster.ticker==ticker).first()
File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/query.py",
line 2895, in first
ret = list(self[0:1]) File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/query.py", line
2687, in getitem
return list(res) File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/query.py", line
2994, in iter
self.session._autoflush() File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py",
line 1493, in _autoflush
self.flush() File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py",
line 2313, in flush
self._flush(objects) File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py",
line 2400, in _flush
subtransactions=True) File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py",
line 865, in begin
nested=nested) File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py",
line 297, in _begin
self._assert_active() File "/anaconda3/lib/python3.7/site-packages/sqlalchemy/orm/session.py",
line 264, in _assert_active
"This session is in 'prepared' state; no further " sqlalchemy.exc.InvalidRequestError: This session is in 'prepared'
state; no further SQL can be emitted within this transaction.
There may be other issues with your code but an obvious one is that you share your session with multiple threads.
Instead of setting a global session, these should be created in each thread.
I am not able to run your code but you could try something like this:
Remove the global session variable completely. You do not need it. Then modify your methods and thread to include a local session:
#classmethod
def find_by_ticker(cls,ticker, session):
return session.query(StockMaster).filter(StockMaster.ticker==ticker).first()
...
class Stream(Thread):
def __init__(self,ticker):
Thread.__init__(self)
self.ticker=ticker
self.quote=1
self.session = Session()
self.data_set = StockLive.find_by_ticker(self.ticker, self.session)
self.count=0
Or something like that. This will now make each thread have their own session and your code will start behaving better.
I'm trying to shard my database into two: one for my main objects, another for logs. Right now, my code looks something like this:
engine = create_engine('postgresql+psycopg2://postgres:password#localhost:5432/logs')
engine2 = create_engine('postgresql+psycopg2://postgres:password#localhost:5432/logs')
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
binds = {'thing': engine,
'log': engine_a}
DBSession.configure(binds=binds)
Base = declarative_base(bind=engine)
Base2 = declarative_base(bind=engine2)
class Thing(Base):
...
class Log(Base2):
...
Where I have more tables using both Base and Base2 as well as inherited objects. I've also tried doing the following:
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension(), bind=engine))
DBSession2 = scoped_session(sessionmaker(extension=ZopeTransactionExtension(), bind=engine2))
However, using either way and only working with objects in Base, not Base2, I get the following error when querying:
return DBSession.query(cls).filter(func.lower(cls.name) == name.lower()).first()
File "build/bdist.macosx-10.7-intel/egg/sqlalchemy/orm/scoping.py", line 113, in do
File "build/bdist.macosx-10.7-intel/egg/sqlalchemy/orm/session.py", line 969, in query
File "build/bdist.macosx-10.7-intel/egg/sqlalchemy/orm/query.py", line 107, in __init__
File "build/bdist.macosx-10.7-intel/egg/sqlalchemy/orm/query.py", line 116, in _set_entities
File "build/bdist.macosx-10.7-intel/egg/sqlalchemy/orm/query.py", line 131, in _setup_aliasizers
File "build/bdist.macosx-10.7-intel/egg/sqlalchemy/orm/util.py", line 550, in _entity_info
File "build/bdist.macosx-10.7-intel/egg/sqlalchemy/orm/mapper.py", line 2861, in configure_mappers
File "build/bdist.macosx-10.7-intel/egg/sqlalchemy/orm/mapper.py", line 1166, in _post_configure_properties
File "build/bdist.macosx-10.7-intel/egg/sqlalchemy/orm/interfaces.py", line 128, in init
File "build/bdist.macosx-10.7-intel/egg/sqlalchemy/orm/properties.py", line 913, in do_init
File "build/bdist.macosx-10.7-intel/egg/sqlalchemy/orm/properties.py", line 969, in _process_dependent_arguments
File "build/bdist.macosx-10.7-intel/egg/sqlalchemy/ext/declarative.py", line 1346, in return_cls
File "<string>", line 1, in <module>
AttributeError: 'Table' object has no attribute 'id'
Of course my table has an attribute 'id', all the same code works as long as I only have one DBSession and one Base. What am I doing wrong?
I found out the problem. I simply had to initiate DBSession().
I have two tables, testInstance and bugzilla that are associated by a third one, bzCheck, like this:
class Instance(Base):
__tablename__ = "testInstance"
id = Column(Integer, primary_key=True)
bz_checks = relation(BZCheck, backref="instance")
class BZCheck(Base):
__tablename__ = "bzCheck"
instance_id = Column(Integer, ForeignKey("testInstance.id"), primary_key=True)
bz_id = Column(Integer, ForeignKey("bugzilla.id"), primary_key=True)
status = Column(String, nullable=False)
bug = relation(Bugzilla, backref="checks")
class Bugzilla(Base):
__tablename__ = "bugzilla"
id = Column(Integer, primary_key=True)
The backend is a postgresql server ; I'm using SQLalchemy 0.5
If I create the Instance, Bugzilla and BZCheck ojects, then do
bzcheck.bug = bugzilla
instance.bz_checks.append(bzcheck)
and then add and commit them ; everything is fine.
But now, let's assume I have an existing instance and an existing bugzilla and want to associate them:
instance = session.query(Instance).filter(Instance.id == 31).one()
bugzilla = session.query(Bugzilla).filter(Bugzilla.id == 19876).one()
check = BZCheck(status="OK")
check.bug = bugzilla
instance.bz_checks.append(check)
It fails:
In [6]: instance.bz_checks.append(check)
2012-01-09 18:43:50,713 INFO sqlalchemy.engine.base.Engine.0x...3bd0 select nextval('"bzCheck_instance_id_seq"')
2012-01-09 18:43:50,713 INFO sqlalchemy.engine.base.Engine.0x...3bd0 None
2012-01-09 18:43:50,713 INFO sqlalchemy.engine.base.Engine.0x...3bd0 ROLLBACK
It tries to get a new ID from an unexisting sequence instead of using the foreign key "testInstance.id"... I don't understand why.
I have had similar problems when trying to modify objects after commiting them ; I should have missed something fundamental but what ?
the part you're missing here is the stack trace. Always look at the stack trace - what is critical here is that it's autoflush, produced by the access of instance.bz_checks:
Traceback (most recent call last):
File "test.py", line 44, in <module>
instance.bz_checks.append(check)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/attributes.py", line 168, in __get__
return self.impl.get(instance_state(instance),dict_)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/attributes.py", line 453, in get
value = self.callable_(state, passive)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/strategies.py", line 563, in _load_for_state
result = q.all()
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/query.py", line 1983, in all
return list(self)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/query.py", line 2092, in __iter__
self.session._autoflush()
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/session.py", line 973, in _autoflush
self.flush()
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/session.py", line 1547, in flush
self._flush(objects)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/session.py", line 1616, in _flush
flush_context.execute()
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/unitofwork.py", line 328, in execute
rec.execute(self)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/unitofwork.py", line 472, in execute
uow
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/mapper.py", line 2291, in _save_obj
execute(statement, params)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/engine/base.py", line 1405, in execute
params)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/engine/base.py", line 1538, in _execute_clauseelement
compiled_sql, distilled_params
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/engine/base.py", line 1646, in _execute_context
context)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/engine/base.py", line 1639, in _execute_context
context)
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/engine/default.py", line 330, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.IntegrityError: (IntegrityError) null value in column "instance_id" violates not-null constraint
'INSERT INTO "bzCheck" (bz_id, status) VALUES (%(bz_id)s, %(status)s) RETURNING "bzCheck".instance_id' {'status': 'OK', 'bz_id': 19876}
you can see this because the line of code is:
instance.bz_checks.append(check)
then autoflush:
self.session._autoflush()
File "/Users/classic/dev/sqlalchemy/lib/sqlalchemy/orm/session.py", line 973, in _autoflush
Three solutions:
a. temporarily disable autoflush (see http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DisableAutoflush)
b. ensure that the BZCheck association object is always created with it's full state needed before accessing any collections:
BZState(bug=bugzilla, instance=instance)
(this is usually a good idea for association objects - they represent the association between two points so it's most appropriate that they be instantiated with this state)
c. change the cascade rules so that the operation of check.bug = somebug doesn't actually place check into the session just yet. You can do this with cascade_backrefs, described at http://www.sqlalchemy.org/docs/orm/session.html#controlling-cascade-on-backrefs. (but you'd need to be on 0.6 or 0.7)
I've model which represents settings in my system and I use it from another part of my application so that import has 3 levels WORKING CODE <- Module <- Model
Model Variables
from django.db import models
class Variables(models.Model):
key = models.CharField(max_length = 20, verbose_name = 'Variable')
value = models.CharField(max_length = 1024)
class Meta:
app_label = 'core'
def __unicode__(self):
return '%s: %s' % (self.key, self.value,)
Here is the code I'm using it from
Module variables.py
from core.models.storage import Variables
def get_var(name):
return Variables.objects.get(key = name)
Module config.py
var = get_var('some_key')
When I use this stuff from django shell everything works well but when I call get_var function I've ImportError exception
storage.py
from django.db import models
class Variables(models.Model):
key = models.CharField(max_length = 20, verbose_name = 'Variable')
value = models.CharField(max_length = 1024)
class Meta:
app_label = 'core'
def __unicode__(self):
return '%s: %s' % (self.key, self.value,)
File "monitor_cli.py", line 19, in
print worker.get_provider()
File "/home/sultan/Project/monitor/app/worker.py", line 14, in get_provider
print Variables.objects.get(pk=1)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/manager.py", line 132, in get
return self.get_query_set().get(*args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 341, in get
clone = self.filter(*args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 550, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/query.py", line 568, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/query.py", line 1172, in add_q
can_reuse=used_aliases, force_having=force_having)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/query.py", line 1060, in add_filter
negate=negate, process_extras=process_extras)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/sql/query.py", line 1226, in setup_joins
field, model, direct, m2m = opts.get_field_by_name(name)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/options.py", line 307, in get_field_by_name
cache = self.init_name_map()
File "/usr/local/lib/python2.6/dist-packages/django/db/models/options.py", line 337, in init_name_map
for f, model in self.get_all_related_m2m_objects_with_model():
File "/usr/local/lib/python2.6/dist-packages/django/db/models/options.py", line 414, in get_all_related_m2m_objects_with_model
cache = self._fill_related_many_to_many_cache()
File "/usr/local/lib/python2.6/dist-packages/django/db/models/options.py", line 428, in _fill_related_many_to_many_cache
for klass in get_models():
File "/usr/local/lib/python2.6/dist-packages/django/db/models/loading.py", line 167, in get_models
self._populate()
File "/usr/local/lib/python2.6/dist-packages/django/db/models/loading.py", line 61, in _populate
self.load_app(app_name, True)
File "/usr/local/lib/python2.6/dist-packages/django/db/models/loading.py", line 76, in load_app
app_module = import_module(app_name)
File "/usr/local/lib/python2.6/dist-packages/django/utils/importlib.py", line 35, in import_module
__import__(name)
ImportError: No module named c
Get rid of the models directory, and put all your models in a models.py file, unless you have a VERY good reason not to. Change your imports to from core.models import Variable (rename your Variables class to Variable - django models should be named as the singular not the plural).
The problem probably has to do with the fact that your models live in namespaces other than models; ie. models.storage. The django infrastructure expects certain things to be in certain places. If you're going to put models in separate namespaces like you're doing, you should be importing them from the __init__.py file within the models module. Don't do this, again, unless you have a very good reason.
Finally, when asking questions of this nature, you should provide a lot more information. You should show the code of all of the relevant files. You should provide detail on what you've done that deviates from the convention of django (in this case, a models directory rather than a models.py file). You should also show relevant settings from settings.py, in this case, your INSTALLED_APPS setting. You should also tell us what version of django and python you are using; this is sometimes relevant. More information upfront is much better than less information.