Pubsub to BQ load using beam - google-bigquery

I am trying to create beam code which will just load the data from pubsub to bq, when i am running the same code from colab its working perfectly but when i am creating template or dataflow as running i am getting issues not define etc.
Error = Invalid JSON payload received. Unknown name "json" at 'rows[0]': Proto field is not repeating, cannot start list. [while running 'Write Raw Data to BQ/_StreamToBigQuery/StreamInsertRows/ParDo(BigQueryWriteFn)-ptransform-60']
line 179, in process UnboundLocalError: local variable 'job' referenced before assignment [while running 'Write Raw Data to Big Query-ptransform-63'] passed through: ==> dist_proc/dax/workflow/worker/fnapi_service_impl.cc:922
Code :
import argparse
import json
import os
import logging
import pandas as pd
import apache_beam as beam
from google.cloud import bigquery, pubsub_v1
from google.cloud.bigquery import table
import google.cloud.storage.client as gcs
from apache_beam.options.pipeline_options import PipelineOptions, StandardOptions, GoogleCloudOptions, SetupOptions
import apache_beam.transforms.window as window
serviceAccount = '/content/test-project-0c3a740e58c8.json'
os.environ["GOOGLE_APPLICATION_CREDENTIALS"]= serviceAccount
logging.basicConfig(level=logging.INFO)
logging.getLogger().setLevel(logging.INFO)
project_id = "test-project"
bigquery_dataset = "bq_load"
bigquery_message_table = "message_table"
bigquery_error_table = "Error_Table"
bigquery_message_agg_table = "message_table_aggri"
subscription_id = "topic_message-sub"
INPUT_SUBSCRIPTION = pubsub_v1.SubscriberClient().subscription_path(project_id, subscription_id)
WINDOW_SIZE = 100
client = bigquery.Client(project = project_id)
bq_dataset = client.dataset(bigquery_dataset)
bq_msg_table = bq_dataset.table(bigquery_message_table)
bq_err_table = bq_dataset.table(bigquery_error_table)
bq_agg_table = bq_dataset.table(bigquery_message_agg_table)
message_table_schema = {
'name': 'MessageType',
'type': 'STRING',
'mode': 'NULLABLE'
}, {
'name': 'Location',
'type': 'STRING',
'mode': 'NULLABLE'
}, {
'name': 'Building',
'type': 'STRING',
'mode': 'NULLABLE'
}, {
'name': 'DateTime',
'type': 'DATETIME',
'mode': 'NULLABLE'
}, {
'name': 'ID',
'type': 'STRING',
'mode': 'NULLABLE'
}, {
'name': 'TID',
'type': 'STRING',
'mode': 'NULLABLE'
}
error_table_schema = {
'name': 'Message',
'type': 'STRING',
'mode': 'NULLABLE'
}, {
'name': 'Error',
'type': 'STRING',
'mode': 'NULLABLE'
}
table_schema_agri = {
'name': 'MessageType',
'type': 'STRING',
'mode': 'NULLABLE'
}, {
'name': 'Location',
'type': 'STRING',
'mode': 'NULLABLE'
}, {
'name': 'Building',
'type': 'STRING',
'mode': 'NULLABLE'
}, {
'name': 'ID',
'type': 'STRING',
'mode': 'NULLABLE'
}, {
'name': 'TID',
'type': 'STRING',
'mode': 'NULLABLE'
}, {
'name': 'no_of_rows',
'type': 'NUMERIC',
'mode': 'NULLABLE'
}
def format_schema(schema):
formatted_schema = []
column_list = []
for row in schema:
formatted_schema.append(bigquery.SchemaField(row['name'], row['type'], row['mode']))
column_list.append(row['name'])
return formatted_schema, set(column_list)
message_job_config = bigquery.LoadJobConfig()
message_job_config.source_format = bigquery.SourceFormat.NEWLINE_DELIMITED_JSON
message_job_config.schema, message_column_list = format_schema(message_table_schema)
print(message_column_list)
error_job_config = bigquery.LoadJobConfig()
error_job_config.source_format = bigquery.SourceFormat.NEWLINE_DELIMITED_JSON
error_job_config.schema, error_column_list = format_schema(error_table_schema)
print(error_column_list)
agg_job_config = bigquery.LoadJobConfig()
agg_job_config.source_format = bigquery.SourceFormat.NEWLINE_DELIMITED_JSON
agg_job_config.schema, agg_column_list = format_schema(table_schema_agri)
print(agg_column_list)
class ProcessMessage(beam.DoFn):
def process(self, message):
json_object = []
try:
message_str = message.decode("utf-8")
json_message = eval(message_str)
if isinstance(json_message, dict) and set(message_column_list).issubset(json_message.keys()):
print('{}'.format(("Formatted message", json_message)))
yield tuple(["Formatted message", json_message])
else:
print('{}'.format(("Error_Message", {"Original_Message": json_message, "Error": 'Unable to map input to table schema'})))
yield tuple(["Error_Message", {"Original_Message": json_message, "Error": 'Unable to map input to table schema'}])
except Exception as e:
print('{}'.format(("Error_Message", {"Original_Message": message_str if message_str else message, "Error": str(e)})))
yield tuple(["Error_Message", {"Original_Message": message_str if message_str else message, "Error": str(e)}])
class WriteDataframeToBQ(beam.DoFn):
def process(self, message):
global project_id
global bigquery_dataset
global bigquery_message_table
global bigquery_error_table
global bigquery_message_agg_table
global subscription_id
global client
global bq_dataset
global bq_msg_table
global bq_err_table
global bq_agg_table
if message[0] == 'Formatted message':
try:
print('Now inserting:', message[1])
job = client.load_table_from_json(message[1], BQ_MSG_TABLE, job_config = message_job_config)
job.result() # Waits for the job to complete.
print('Total {} messages successfully written to BigQuery Messsage Table'.format(len(message[1])))
# Creating aggregation dataframe
df = pd.DataFrame(message[1])
count_df= df.groupby(['MessageType','Location','Building','ID','TID']).size().reset_index(name='no_of_rows')
job = client.load_table_from_json(count_df.to_dict('records'), BQ_AGG_TABLE, job_config = agg_job_config)
job.result() # Waits for the job to complete.
print('Total {} messages successfully written to BigQuery Agree Messsage Table'.format(str(count_df.shape[0])))
except Exception as e:
# print(job.errors)
raise e
else:
try:
error_rows = [{"Message": json.dumps(m["Original_Message"]) if isinstance(m["Original_Message"], dict) else str(m["Original_Message"]), "Error": m["Error"]} for m in message[1]]
print('Now inserting:', error_rows)
job = client.load_table_from_json(error_rows, BQ_ERR_TABLE, job_config = error_job_config)
job.result() # Waits for the job to complete.
print('Total {} messages successfully written to BigQuery Error Table'.format(len(error_rows)))
except Exception as e:
#print(job.errors)
raise e
def run():
pipeline_options = {
'project': 'test-project',
'runner': 'DataflowRunner',
'region': 'us-east1',
'staging_location': 'gs://bucket12345/tmp/',
'temp_location': 'gs://bucket12345/tmp/',
'template_location': 'gs://bucket12345/template/dataflow_test_template',
'streaming': True
}
pipeline_options = PipelineOptions.from_dictionary(pipeline_options)
table = 'test-project:bq_load.message_table'
with beam.Pipeline(options=pipeline_options) as p:
( p
| "ReadFromPubSub" >> beam.io.gcp.pubsub.ReadFromPubSub(
subscription=INPUT_SUBSCRIPTION, timestamp_attribute=None
)
| "Process Message" >> beam.ParDo(ProcessMessage())
| 'Fixed-size windows' >> beam.WindowInto(window.FixedWindows(WINDOW_SIZE))
| beam.GroupByKey()
| "Write Raw Data to Big Query" >> beam.ParDo(WriteDataframeToBQ())
| "Write Raw Data to BQ" >> beam.io.WriteToBigQuery(
table,custom_gcs_temp_location = 'gs://bucket12345/template/dataflow_test_template')
)
run()

Related

Pandas boolean condition from nested list of dictionaries

[{'id': 123,
'type': 'salary', #Parent node
'tx': 'house',
'sector': 'EU',
'transition': [{'id': 'hash', #Child node
'id': 123,
'type': 'salary',
'tx': 'house' }]},
{'userid': 123,
'type': 'salary', #Parent node
'tx': 'office',
'transition': [{'id': 'hash', # Child node
'id': 123,
'type': 'salary',
'tx': 'office'}]}]
As a pandas column ('info') I have some information stored as a nested list of dictionaries like the example above.
What I'm trying to do is a boolean condition whether this list has the following attributes:
More than one 'type' == 'salary' in any of all parents nodes
Field 'tx' is different in any of all parents nodes with 'type' == 'salary'
So far I've tried to flatten a list and filter but it is not solving the first and seconds nodes
a = df.iloc[0].info
values = [item for sublist in [[list(i.values()) for i in a]][0]for item in sublist]
If you want to one line solution, you can use:
df['check'] = df['info'].apply(lambda x: True if sum([1 if i['type']=='salary' else 0 for i in x]) > 1 and [i['tx'] for i in x if i['type']=='salary'].count([i['tx'] for i in x if i['type']=='salary'][0]) != len([i['tx'] for i in x if i['type']=='salary']) else False)
or (expanded):
def check(x):
total_salary = sum([1 if i['type']=='salary' else 0 for i in x]) # get count of "type": "salary" matches
tx_list = [i['tx'] for i in x if i['type']=='salary'] # get tx values when type==salary
tx_check = tx_list.count(tx_list[0]) != len(tx_list) # check all values are same in tx_list
if total_salary > 1 and tx_check:
return True
else:
return False
df['check'] = df['info'].apply(check)

Passing Dataframe column as variable to a dict in a loop

I have a Dataframe with 2 columns as below:
name, type
prod_a, fruit
prod_b, vegetable
prod_c, fruit
I am trying to pass these two columns to the below dict in a loop:
data = {"name": df['name'],
"accountId": df['type']}
How could I pass values from the Dataframe into the above dict data
If want loop by each row and create dictionaries separately use:
for x, y in df[['name','type']].values:
data = {"name": x, "accountId": y}
print (data)
{'name': 'prod_a', 'accountId': 'fruit'}
{'name': 'prod_b', 'accountId': 'vegetable'}
{'name': 'prod_c', 'accountId': 'fruit'}
Or rename column and use DataFrame.to_dict with r for method records:
for data in df[['name','type']].rename(columns={'type':'accountId'}).to_dict('r'):
print (data)
{'name': 'prod_a', 'accountId': 'fruit'}
{'name': 'prod_b', 'accountId': 'vegetable'}
{'name': 'prod_c', 'accountId': 'fruit'}
If need same output use DataFrame.to_dict with l for method list:
data = df[['name','type']].rename(columns={'type':'accountId'}).to_dict('l')
print (data)
{'name': ['prod_a', 'prod_b', 'prod_c'],
'accountId': ['fruit', 'vegetable', 'fruit']}
IIUC:
df = pd.DataFrame({
'name': ['prod_a', 'prod_b', 'prod_c'],
'type': ['fruit', 'vegetable', 'fruit']
})
data = dict()
for i in list(df.columns):
data.update({('accountId' if i=='type' else i): list(df[i])})
print(data)
{'name': ['prod_a', 'prod_b', 'prod_c'],
'accountId': ['fruit', 'vegetable', 'fruit']}

Using Json Input Variables In Airflow EMR Operator Steps

I'm currently following the template given here: https://github.com/apache/airflow/blob/master/airflow/contrib/example_dags/example_emr_job_flow_manual_steps.py to create a DAG to call for a emr instance using spark submit. When setting up the spark_test_steps, I need to include variables passed in from a POST Json to fill the spark submit like below:
SPARK_TEST_STEPS = [
{
'Name': 'calculate_pi',
'ActionOnFailure': 'CONTINUE',
'HadoopJarStep': {
'Jar': 'command-runner.jar',
'Args': [
'/usr/lib/spark/bin/run-example',
'SparkPi',
kwargs['dag_run'].conf['var_1']
kwargs['dag_run'].conf['var_2']
'10'
]
}
}
]
How can I pass in variables given by the POST Json while still following the format given in the git link to look like below?
from datetime import timedelta
import airflow
from airflow import DAG
from airflow.contrib.operators.emr_create_job_flow_operator import EmrCreateJobFlowOperator
from airflow.contrib.operators.emr_add_steps_operator import EmrAddStepsOperator
from airflow.contrib.sensors.emr_step_sensor import EmrStepSensor
from airflow.contrib.operators.emr_terminate_job_flow_operator import EmrTerminateJobFlowOperator
DEFAULT_ARGS = {
'owner': 'Airflow',
'depends_on_past': False,
'start_date': airflow.utils.dates.days_ago(2),
'email': ['airflow#example.com'],
'email_on_failure': False,
'email_on_retry': False
}
dag = DAG(
'emr_job_flow_manual_steps_dag',
default_args=DEFAULT_ARGS,
dagrun_timeout=timedelta(hours=2),
schedule_interval='0 3 * * *'
)
var_1 = ''
var_2 = ''
SPARK_TEST_STEPS = []
def define_param(**kwargs):
global var_1
global var_2
global SPARK_TEST_STEPS
var_1 = str(kwargs['dag_run'].conf['var_1'])
var_2 = str(kwargs['dag_run'].conf['var_2'])
SPARK_TEST_STEPS = [
{
'Name': 'calculate_pi',
'ActionOnFailure': 'CONTINUE',
'HadoopJarStep': {
'Jar': 'command-runner.jar',
'Args': [
'/usr/lib/spark/bin/run-example',
'SparkPi',
kwargs['dag_run'].conf['var_1']
kwargs['dag_run'].conf['var_2']
'10'
]
}
}
]
return SPARK_TEST_STEPS
DEFINE_PARAMETERS = PythonOperator(
task_id='DEFINE_PARAMETERS',
python_callable=define_param,
provide_context=True,
dag=dag)
cluster_creator = EmrCreateJobFlowOperator(
task_id='create_job_flow',
job_flow_overrides=JOB_FLOW_OVERRIDES,
aws_conn_id='aws_default',
emr_conn_id='emr_default',
dag=dag
)
step_adder = EmrAddStepsOperator(
task_id='add_steps',
job_flow_id="{{ task_instance.xcom_pull('create_job_flow', key='return_value') }}",
aws_conn_id='aws_default',
steps='{{ ti.xcom_pull(task_ids="DEFINE_PARAMETERS") }}',
dag=dag
)
step_checker = EmrStepSensor(
task_id='watch_step',
job_flow_id="{{ task_instance.xcom_pull('create_job_flow', key='return_value') }}",
step_id="{{ task_instance.xcom_pull('add_steps', key='return_value')[0] }}",
aws_conn_id='aws_default',
dag=dag
)
cluster_remover = EmrTerminateJobFlowOperator(
task_id='remove_cluster',
job_flow_id="{{ task_instance.xcom_pull('create_job_flow', key='return_value') }}",
aws_conn_id='aws_default',
dag=dag
)
cluster_creator.set_downstream(step_adder)
step_adder.set_downstream(step_checker)
step_checker.set_downstream(cluster_remover)
I cannot use Variable.get and Variable.set as this will not allow multiple dag calls for different variable types at the same time due to the constant changing of airflow global variables. I have tried calling SPARK_TEST_STEPS using xcom but the return type of xcom is string and EmrAddStepsOperator steps requires a list.
I solved a similar problem by creating a custom operator that parses the json prior to executing. The cause of the problem is that when you pass steps='{{ ti.xcom_pull(task_ids="DEFINE_PARAMETERS") }}',. you are literally passing a string with the value interpolated by the templating engine, it is not deserialized.
from airflow.contrib.hooks.emr_hook import EmrHook
from airflow.exceptions import AirflowException
from airflow.models import BaseOperator
from airflow.utils.decorators import apply_defaults
from airflow.contrib.operators.emr_add_steps_operator import EmrAddStepsOperator
import json
class DynamicEmrStepsOperator(EmrAddStepsOperator):
template_fields = ['job_flow_id', 'steps']
template_ext = ()
ui_color = '#f9c915'
#apply_defaults
def __init__(
self,
job_flow_id=None,
steps="[]",
*args, **kwargs):
super().__init__(
job_flow_id = job_flow_id,
steps = steps,
*args, **kwargs)
def execute(self, context):
self.steps = json.loads(self.steps)
return super().execute(context)

Displaying custom message

I'm trying to display a custom message box from my custom module called 'xx_project'
The code below is from a class I made that contains the warning. I then want to call this warning from my custom module 'xx_project'
class warning(osv.osv_memory):
_name = 'warning'
_description = 'warning'
_columns = {
'type': fields.selection(WARNING_TYPES, string='Type', readonly=True),
'title': fields.char(string="Title", size=100, readonly=True),
'message': fields.text(string="Message", readonly=True),
}
_req_name = 'title'
def _get_view_id(self, cr, uid):
"""Get the view id
#return: view id, or False if no view found
"""
res = self.pool.get('ir.model.data').get_object_reference(cr, uid,
'xx_project', 'warning_form')
return res and res[1] or False
def message(self, cr, uid, id, context):
message = self.browse(cr, uid, id)
message_type = [t[1] for t in WARNING_TYPES if message.type == t[0]][0]
print '%s: %s' % (_(message_type), _(message.title))
res = {
'name': '%s: %s' % (_(message_type), _(message.title)),
'view_type': 'form',
'view_mode': 'form',
'view_id': self._get_view_id(cr, uid),
'res_model': 'warning',
'domain': [],
'context': context,
'type': 'ir.actions.act_window',
'target': 'new',
'res_id': message.id
}
return res
def info(self, cr, uid, title, message, context=None):
id = self.create(cr, uid, {'title': title, 'message': message, 'type': 'info'})
res = self.message(cr, uid, id, context)
return res
And then finally in xx_project I have a field named 'xx_message' that calls the function 'get_message'.
get_message looks like this:
def get_message(self, cr, uid, ids, name, args, context=None):
return self.pool.get('warning').info(cr, uid, title='Export imformation',
message="%s products Created, %s products Updated " % (
"test", "test"))
And 'xx_message':
_columns = {
'xx_message': fields.function(get_message)
}
I keep getting a Keyerror when I try and run this code, any ideas?

Django: object needs to have a value for field "..." before this many-to-many relationship can be used

I experience a strange error with Django 1.5:
I have defined a model like below:
class Company(models.Model):
user = models.OnetoOneField(User)
agreed_to_terms = models.NullBooleanField(default=False)
address = models.CharField(_('Complete Address'),
max_length = 255, null = True, blank = True)
winning_bid = models.ForeignKey('Bid',
related_name='winning_bid',
blank = True, null = True)
bid_list = models.ManyToManyField('Bid',
related_name='bids',
blank = True, null = True)
...
class Bid(models.Model):
user = models.ForeignKey(User, null = True, blank = True)
description = models.TextField(_('Description'),
blank = True, null = True,)
volume = models.DecimalField(max_digits=7, decimal_places=3,
null=True, blank=True,)
...
# all other attributes are of the Boolean, CharField or DecimalField type. No Foreignkeys, nor ManytoManyFields.
When I try to file the form with the initial data through the Django admin, I get the following error:
Exception Value:
"" needs to have a value for field "company" before this many-to-many relationship can be used.
Please see the traceback below.
The error message does not make very much sense to me. The only m2m relationship is bid_list, which is null = True and was null at the time of saving.
Is there something new in Django 1.5, which I have not discovered while reading the changelog (this is my first project in Django 1.5)?
Interestingly, when I save an object in the Django shell, I do not get an error message, but the object does not get saved without any error message.
In [1]: user = User.objects.get(username='admin')
In [2]: new_company = Company()
In [3]: new_company.user = user
In [4]: new_company.save() Out[4]: <Company: Company object>
In [5]: foo = Company.objects.all()
Out[5]: []
When I try to trace the SQL statements with the debug toolbar, I can only see SQL SELECT statements, no INSERT requests.
What is the explanation for this strange behaviour?
Traceback:
Request Method: POST
Request URL: /admin/company/company/add/
Django Version: 1.5.1
Python Version: 2.7.1
Installed Applications:
('django.contrib.admin',
'django.contrib.admindocs',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.gis',
'django.contrib.humanize',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'django.contrib.admindocs',
'crispy_forms',
'django_extensions',
'easy_thumbnails',
'registration',
'south',
'company',
'bid',
'debug_toolbar')
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'debug_toolbar.middleware.DebugToolbarMiddleware')
Traceback:
File "/Users/neurix/Development/virtual/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
115. response = callback(request, *callback_args, **callback_kwargs)
File "/Users/neurix/Development/virtual/lib/python2.7/site-packages/django/contrib/admin/options.py" in wrapper
372. return self.admin_site.admin_view(view)(*args, **kwargs)
File "/Users/neurix/Development/virtual/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
91. response = view_func(request, *args, **kwargs)
File "/Users/neurix/Development/virtual/lib/python2.7/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
89. response = view_func(request, *args, **kwargs)
File "/Users/neurix/Development/virtual/lib/python2.7/site-packages/django/contrib/admin/sites.py" in inner
202. return view(request, *args, **kwargs)
File "/Users/neurix/Development/virtual/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapper
25. return bound_func(*args, **kwargs)
File "/Users/neurix/Development/virtual/lib/python2.7/site-packages/django/utils/decorators.py" in _wrapped_view
91. response = view_func(request, *args, **kwargs)
File "/Users/neurix/Development/virtual/lib/python2.7/site-packages/django/utils/decorators.py" in bound_func
21. return func(self, *args2, **kwargs2)
File "/Users/neurix/Development/virtual/lib/python2.7/site-packages/django/db/transaction.py" in inner
223. return func(*args, **kwargs)
File "/Users/neurix/Development/virtual/lib/python2.7/site-packages/django/contrib/admin/options.py" in add_view
1008. self.save_related(request, form, formsets, False)
File "/Users/neurix/Development/virtual/lib/python2.7/site-packages/django/contrib/admin/options.py" in save_related
762. form.save_m2m()
File "/Users/neurix/Development/virtual/lib/python2.7/site-packages/django/forms/models.py" in save_m2m
84. f.save_form_data(instance, cleaned_data[f.name])
File "/Users/neurix/Development/virtual/lib/python2.7/site-packages/django/db/models/fields/related.py" in save_form_data
1336. setattr(instance, self.attname, data)
File "/Users/neurix/Development/virtual/lib/python2.7/site-packages/django/db/models/fields/related.py" in __set__
910. manager = self.__get__(instance)
File "/Users/neurix/Development/virtual/lib/python2.7/site-packages/django/db/models/fields/related.py" in __get__
897. through=self.field.rel.through,
File "/Users/neurix/Development/virtual/lib/python2.7/site-packages/django/db/models/fields/related.py" in __init__
586. (instance, source_field_name))
Exception Type: ValueError at /admin/company/company/add/
Exception Value: "<Company: Company object>" needs to have a value for field "company" before this many-to-many relationship can be used.
settings.py
import os, os.path, sys
DEBUG = True
TEMPLATE_DEBUG = DEBUG
# Setting up folders
abspath = lambda *p: os.path.abspath(os.path.join(*p))
PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
TASK2_MODULE_PATH = abspath(PROJECT_ROOT, 'apps/')
sys.path.insert(0, TASK2_MODULE_PATH)
# Loading passwords
try:
from settings_pwd import *
except ImportError:
pass
AUTH_PROFILE_MODULE = 'profile.UserProfile'
#ALLOWED_HOSTS = [''] # not needed for DEBUG = True
TIME_ZONE = 'Europe/London'
LANGUAGE_CODE = 'en-uk'
LANGUAGES = [
("en", u"English"),
]
SITE_ID = 1
USE_I18N = True
USE_L10N = True
USE_TZ = True
if DEBUG:
MEDIA_ROOT = os.path.join(PROJECT_ROOT, "site_media", "media")
else:
MEDIA_ROOT = "folder_to_upload_files"
if DEBUG:
MEDIA_URL = "/media/"
else:
MEDIA_URL = "/media/uploads/"
if DEBUG:
STATIC_ROOT = os.path.join(PROJECT_ROOT, "site_media","static")
else:
STATIC_ROOT = "folder_to_static_files"
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(PROJECT_ROOT, "assets"),
)
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
)
SECRET_KEY = '...'
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',)
ROOT_URLCONF = 'task2.urls'
WSGI_APPLICATION = 'task2.wsgi.application'
TEMPLATE_DIRS = (
os.path.join(PROJECT_ROOT, "templates"),
os.path.join(PROJECT_ROOT, "templates/pages"),)
INSTALLED_APPS = (
# Django apps
'django.contrib.admin',
'django.contrib.admindocs',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.gis',
'django.contrib.humanize',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.admin',
'django.contrib.admindocs',
# third party apps
'crispy_forms',
'django_extensions',
'easy_thumbnails',
'registration',
'south',
# task2 apps
'profile',
'company',
)
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
)
log = DEBUG
if log:
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'simple': {
'format': '%(levelname)s %(message)s',
},
},
'handlers': {
'console':{
'level':'DEBUG',
'class':'logging.StreamHandler',
'formatter': 'simple'
},
},
'loggers': {
'django': {
'handlers': ['console'],
'level': 'DEBUG',
},
}
}
####################
# THIRD PARTY SETUPS
# For Crispy Forms
CRISPY_FAIL_SILENTLY = not DEBUG
CRISPY_TEMPLATE_PACK = 'bootstrap'
## For Django Registration
ACCOUNT_ACTIVATION_DAYS = 7
# for Django testing to avoid conflicts with South migrations
SOUTH_TESTS_MIGRATE = False
# Debug_toolbar settings
if DEBUG:
INTERNAL_IPS = ('127.0.0.1',)
MIDDLEWARE_CLASSES += (
'debug_toolbar.middleware.DebugToolbarMiddleware',
)
INSTALLED_APPS += (
'debug_toolbar',
)
DEBUG_TOOLBAR_PANELS = (
'debug_toolbar.panels.version.VersionDebugPanel',
'debug_toolbar.panels.timer.TimerDebugPanel',
'debug_toolbar.panels.settings_vars.SettingsVarsDebugPanel',
'debug_toolbar.panels.headers.HeaderDebugPanel',
#'debug_toolbar.panels.profiling.ProfilingDebugPanel',
'debug_toolbar.panels.request_vars.RequestVarsDebugPanel',
'debug_toolbar.panels.sql.SQLDebugPanel',
'debug_toolbar.panels.template.TemplateDebugPanel',
'debug_toolbar.panels.cache.CacheDebugPanel',
'debug_toolbar.panels.signals.SignalDebugPanel',
'debug_toolbar.panels.logger.LoggingPanel',
)
DEBUG_TOOLBAR_CONFIG = {
'INTERCEPT_REDIRECTS': False,
}
# Easy_Thumbnail setup
THUMBNAIL_ALIASES = {
'': {
'thumbnail': {'size': (50, 50), 'crop': True},
},
}
The problem has to do with how you use your views.
I think you are using:
instance.add(many_to_many_instance)
before you have an instance id.
so first save your model:
instance.save()
instance.add(many_to_many_instance)
You are using custom user model AUTH_PROFILE_MODULE = 'profile.UserProfile', but in code I suppose you use native django user.
I suppose your models should be like
class Company(models.Model):
user = models.OnetoOneField('profile.UserProfile')
...
read more https://docs.djangoproject.com/en/1.5/ref/contrib/auth/#django.contrib.auth.models.User.get_profile